Merge branch 'integration_2025_w35' into 'develop'
Integration: `2025.w35` * !3604 Consider PDSCH EPRE to DMRS EPRE in NR UE * !3606 Fix SRS TLV unpack * !3602 Update RFsim CN * !3516 [FHI72 M-plane] CM improvements and PM implementation * !3538 add a new graphical T tracer to see gNB MAC scheduling decisions * !3425 RFSim test for 10 UEs/process Closes #950 See merge request oai/openairinterface5g!3610
This commit is contained in:
@@ -455,3 +455,93 @@ l2sim4g_ext_dn:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec l2sim4g-trf-gen ip a show dev eth0
|
||||
CmdPrefix: docker exec l2sim4g-trf-gen
|
||||
|
||||
rfsim5g_multiue1:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue1
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue1
|
||||
AttachScript: docker start rfsim5g-oai-nr-ue
|
||||
DetachScript: docker stop rfsim5g-oai-nr-ue
|
||||
MTU: 1500
|
||||
|
||||
rfsim5g_multiue2:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue2
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue2
|
||||
AttachScript: true
|
||||
DetachScript: true
|
||||
MTU: 1500
|
||||
|
||||
rfsim5g_multiue3:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue3
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue3
|
||||
AttachScript: "true"
|
||||
DetachScript: "true"
|
||||
MTU: 1500
|
||||
|
||||
rfsim5g_multiue4:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue4
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue4
|
||||
AttachScript: "true"
|
||||
DetachScript: "true"
|
||||
MTU: 1500
|
||||
|
||||
rfsim5g_multiue5:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue5
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue5
|
||||
AttachScript: "true"
|
||||
DetachScript: "true"
|
||||
MTU: 1500
|
||||
|
||||
rfsim5g_multiue6:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue6
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue6
|
||||
AttachScript: "true"
|
||||
DetachScript: "true"
|
||||
MTU: 1500
|
||||
|
||||
rfsim5g_multiue7:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue7
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue7
|
||||
AttachScript: "true"
|
||||
DetachScript: "true"
|
||||
MTU: 1500
|
||||
|
||||
rfsim5g_multiue8:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue8
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue8
|
||||
AttachScript: "true"
|
||||
DetachScript: "true"
|
||||
MTU: 1500
|
||||
|
||||
rfsim5g_multiue9:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue9
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue9
|
||||
AttachScript: "true"
|
||||
DetachScript: "true"
|
||||
MTU: 1500
|
||||
|
||||
rfsim5g_multiue10:
|
||||
Host: "%%current_host%%"
|
||||
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue10
|
||||
CmdPrefix: docker exec rfsim5g-oai-nr-ue
|
||||
IF: oaitun_ue10
|
||||
AttachScript: "true"
|
||||
DetachScript: "true"
|
||||
MTU: 1500
|
||||
|
||||
@@ -112,7 +112,7 @@ gNBs =
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -70;
|
||||
p0_nominal = -80;
|
||||
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
@@ -175,7 +175,7 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 180;
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
}
|
||||
);
|
||||
@@ -184,7 +184,7 @@ L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
prach_dtx_threshold = 130;
|
||||
#pucch0_dtx_threshold = 150;
|
||||
}
|
||||
);
|
||||
@@ -198,7 +198,7 @@ RUs = (
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 65;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
sf_extension = 0
|
||||
sdr_addrs = "addr=192.168.80.52,clock_source=internal,time_source=internal"
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
set -x
|
||||
|
||||
sudo mbimcli -p -d /dev/cdc-wdm0 --set-radio-state=off
|
||||
|
||||
IF=wwan0
|
||||
sudo ip link set ${IF} down
|
||||
sudo ip addr flush dev ${IF}
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
<!--
|
||||
|
||||
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>rfsim-5gnr-tdd-multiue</htmlTabRef>
|
||||
<htmlTabName>Monolithic SA TDD gNB multiue</htmlTabName>
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
111111
|
||||
800813
|
||||
000001
|
||||
000002
|
||||
000003
|
||||
000008
|
||||
020001
|
||||
020002
|
||||
020003
|
||||
020004
|
||||
020105
|
||||
444445
|
||||
030001
|
||||
030002
|
||||
444444
|
||||
100001
|
||||
222222
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="111111">
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<svr_id>0</svr_id>
|
||||
<images>oai-gnb-asan oai-nr-ue</images>
|
||||
</testCase>
|
||||
<testCase id="800813">
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
</testCase>
|
||||
<testCase id="000001">
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy OAI 5G CoreNetwork</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
|
||||
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000002">
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy OAI 5G gNB RF sim SA</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
|
||||
<services>oai-gnb</services>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000003">
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
|
||||
<services>oai-nr-ue</services>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000008">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach OAI UE (Wait for IP)</desc>
|
||||
<id>rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10</id>
|
||||
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020001">
|
||||
<class>Ping</class>
|
||||
<desc>Ping ext-dn from NR-UE</desc>
|
||||
<id>rfsim5g_multiue1</id>
|
||||
<nodes>acamas</nodes>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<ping_args>-c 20 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020002">
|
||||
<class>Ping</class>
|
||||
<desc>Ping NR-UE from ext-dn</desc>
|
||||
<id>rfsim5g_ext_dn</id>
|
||||
<nodes>acamas</nodes>
|
||||
<svr_id>rfsim5g_multiue1</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<ping_args>-c 20 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020003">
|
||||
<class>Ping</class>
|
||||
<desc>Ping ext-dn from Second NR-UE</desc>
|
||||
<id>rfsim5g_multiue2</id>
|
||||
<nodes>acamas</nodes>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<ping_args>-c 20 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020004">
|
||||
<class>Ping</class>
|
||||
<desc>Ping Second NR-UE from ext-dn</desc>
|
||||
<id>rfsim5g_ext_dn</id>
|
||||
<nodes>acamas</nodes>
|
||||
<svr_id>rfsim5g_multiue2</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<ping_args>-c 20 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020005">
|
||||
<class>Ping</class>
|
||||
<desc>Ping ext-dn from both UEs</desc>
|
||||
<id>rfsim5g_multiue1 rfsim5g_multiue2</id>
|
||||
<nodes>acamas acamas</nodes>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<ping_args>-c 20 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020105">
|
||||
<class>Ping</class>
|
||||
<desc>Ping ext-dn from all UEs</desc>
|
||||
<id>rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10</id>
|
||||
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<ping_args>-c 20 -i 0.25 -s 1016</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030001">
|
||||
<class>Iperf</class>
|
||||
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
|
||||
<id>rfsim5g_multiue1</id>
|
||||
<nodes>acamas</nodes>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030002">
|
||||
<class>Iperf</class>
|
||||
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 1M -t 20</iperf_args>
|
||||
<id>rfsim5g_multiue1</id>
|
||||
<nodes>acamas</nodes>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="444444">
|
||||
<class>Detach_UE</class>
|
||||
<desc>Detach OAI UEs</desc>
|
||||
<id>rfsim5g_multiue1</id>
|
||||
<nodes>acamas</nodes>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100001">
|
||||
<class>Undeploy_Object</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
|
||||
<d_retx_th>1,0,0,0</d_retx_th>
|
||||
<u_retx_th>1,0,0,0</u_retx_th>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
</testCase>
|
||||
|
||||
<testCase id="222222">
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<svr_id>0</svr_id>
|
||||
<images>oai-gnb-asan oai-nr-ue</images>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
|
||||
@@ -37,9 +37,9 @@ Now pull images.
|
||||
|
||||
```bash
|
||||
$ docker pull mysql:8.0
|
||||
$ docker pull oaisoftwarealliance/oai-amf:v2.1.9
|
||||
$ docker pull oaisoftwarealliance/oai-smf:v2.1.9
|
||||
$ docker pull oaisoftwarealliance/oai-upf:v2.1.9
|
||||
$ docker pull oaisoftwarealliance/oai-amf:v2.1.10
|
||||
$ docker pull oaisoftwarealliance/oai-smf:v2.1.10
|
||||
$ docker pull oaisoftwarealliance/oai-upf:v2.1.10
|
||||
$ docker pull oaisoftwarealliance/trf-gen-cn5g:focal
|
||||
|
||||
$ docker pull oaisoftwarealliance/oai-gnb:develop
|
||||
@@ -52,7 +52,7 @@ $ docker logout
|
||||
|
||||
**CAUTION: 2023/01/27 with the release `v1.5.0` of the `CN5G`, the previous version was not compatible any-more.**
|
||||
|
||||
**This new version is working only with the `v2.1.9` of the `CN5G`.**
|
||||
**This new version is working only with `v2.1.9` or later of the `CN5G`.**
|
||||
|
||||
# 2. Deploy containers #
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
services:
|
||||
mysql:
|
||||
container_name: "rfsim5g-mysql"
|
||||
image: mysql:8.0
|
||||
volumes:
|
||||
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
|
||||
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- MYSQL_DATABASE=oai_db
|
||||
- MYSQL_USER=test
|
||||
- MYSQL_PASSWORD=test
|
||||
- MYSQL_ROOT_PASSWORD=linux
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-amf/etc/config.yaml
|
||||
depends_on:
|
||||
- mysql
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-smf/etc/config.yaml
|
||||
depends_on:
|
||||
- oai-amf
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-upf/etc/config.yaml
|
||||
depends_on:
|
||||
- oai-smf
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
cap_drop:
|
||||
- ALL
|
||||
privileged: true
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.134
|
||||
interface_name: eth0
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.134
|
||||
interface_name: eth1
|
||||
oai-ext-dn:
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-ext-dn
|
||||
image: oaisoftwarealliance/trf-gen-cn5g:focal
|
||||
entrypoint: /bin/bash -c \
|
||||
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
|
||||
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
|
||||
depends_on:
|
||||
- oai-upf
|
||||
networks:
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.135
|
||||
healthcheck:
|
||||
test: /bin/bash -c "ping -c 2 192.168.72.134"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
oai-gnb:
|
||||
image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
|
||||
container_name: rfsim5g-oai-gnb
|
||||
cap_drop:
|
||||
- ALL
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E --rfsim --log_config.global_log_options level,nocolor,time
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
depends_on:
|
||||
- oai-ext-dn
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.140
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band78.106prb.rfsim.yaml:/opt/oai-gnb/etc/gnb.yaml
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
oai-nr-ue:
|
||||
image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop}
|
||||
container_name: rfsim5g-oai-nr-ue
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_ADMIN # for interface bringup
|
||||
- NET_RAW # for ping
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001100 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time --num-ues 10
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.150
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
volumes:
|
||||
- ./nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-uesoftmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
networks:
|
||||
public_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-public-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.71.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-public"
|
||||
traffic_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-traffic-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.72.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-traffic"
|
||||
@@ -0,0 +1,75 @@
|
||||
uicc0 = {
|
||||
imsi = "208990100001100";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
uicc1 = {
|
||||
imsi = "208990100001101";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
uicc2 = {
|
||||
imsi = "208990100001102";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
uicc3 = {
|
||||
imsi = "208990100001103";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
uicc4 = {
|
||||
imsi = "208990100001104";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
uicc5 = {
|
||||
imsi = "208990100001105";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
uicc6 = {
|
||||
imsi = "208990100001106";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
uicc7 = {
|
||||
imsi = "208990100001107";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
uicc8 = {
|
||||
imsi = "208990100001108";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
uicc9 = {
|
||||
imsi = "208990100001109";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst=1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
thread-pool: "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
|
||||
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
|
||||
@@ -23,7 +23,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -35,7 +35,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -47,7 +47,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.9
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
genids
|
||||
tracer/enb
|
||||
tracer/gnb
|
||||
tracer/gnb_mac
|
||||
tracer/extract_config
|
||||
tracer/record
|
||||
tracer/replay
|
||||
|
||||
@@ -92,9 +92,13 @@ ID = UE_PHY_INITIATE_RA_PROCEDURE
|
||||
GROUP = ALL:PHY:UE:WIRESHARK
|
||||
FORMAT = int,frame : int,subframe_or_slot : int,preamble : int,power
|
||||
ID = GNB_PHY_DL_TICK
|
||||
DESC = gNodeB downlink tick - one tick per ms at start of downlink processing
|
||||
DESC = gNodeB downlink tick - one tick per slot at start of downlink processing
|
||||
GROUP = ALL:PHY:GRAPHIC:GNB
|
||||
FORMAT = int,gNB_ID : int,frame : int,subframe
|
||||
FORMAT = int,gNB_ID : int,frame : int,slot
|
||||
ID = GNB_PHY_UL_TICK
|
||||
DESC = gNodeB uplink tick - one tick per slot at start of uplink processing
|
||||
GROUP = ALL:PHY:GRAPHIC:GNB
|
||||
FORMAT = int,gNB_ID : int,frame : int,slot
|
||||
ID = ENB_PHY_MIB
|
||||
DESC = MIB data
|
||||
GROUP = ALL:PHY:ENB:WIRESHARK
|
||||
@@ -221,6 +225,22 @@ ID = NRUE_MAC_DL_RAR_PDU_WITH_DATA
|
||||
DESC = NR MAC downlink PDU for RAR
|
||||
GROUP = ALL:MAC:UE:WIRESHARK
|
||||
FORMAT = int,rnti : int,frame : int,slot : buffer,data
|
||||
ID = GNB_MAC_DL
|
||||
DESC = NR MAC downlink scheduler decision for an UE
|
||||
GROUP = ALL:MAC:GNB
|
||||
FORMAT = int,rnti : int,frame : int,slot : int,mcs : int,tbs
|
||||
ID = GNB_MAC_LCID_DL
|
||||
DESC = NR MAC downlink scheduler decision for an UE for a specific LCID
|
||||
GROUP = ALL:MAC:GNB
|
||||
FORMAT = int,rnti : int,frame : int,slot : int,lcid : int,data_size : int,tx_list_occupancy
|
||||
ID = GNB_MAC_UL
|
||||
DESC = NR MAC uplink scheduler decision for an UE
|
||||
GROUP = ALL:MAC:GNB
|
||||
FORMAT = int,rnti : int,frame : int,slot : int,mcs : int,tbs
|
||||
ID = GNB_MAC_LCID_UL
|
||||
DESC = NR MAC uplink traffic received for an UE for a specific LCID
|
||||
GROUP = ALL:MAC:GNB
|
||||
FORMAT = int,rnti : int,frame : int,slot : int,lcid : int,data_size
|
||||
|
||||
#RLC logs
|
||||
ID = ENB_RLC_DL
|
||||
|
||||
@@ -62,9 +62,13 @@ if(T_TRACER_GUI)
|
||||
tracer_logger tracer_view tracer_events)
|
||||
target_link_libraries(gnb PRIVATE png)
|
||||
|
||||
add_executable(ue ue.c)
|
||||
target_link_libraries(ue PRIVATE tracer_utils tracer_filter tracer_gui
|
||||
add_executable(gnb_mac gnb_mac.c)
|
||||
target_link_libraries(gnb_mac PRIVATE tracer_utils tracer_filter tracer_gui
|
||||
tracer_logger tracer_view tracer_events)
|
||||
|
||||
add_executable(ue ue.c)
|
||||
target_link_libraries(ue PRIVATE tracer_utils tracer_view tracer_gui
|
||||
tracer_logger tracer_filter tracer_events)
|
||||
target_link_libraries(ue PRIVATE png)
|
||||
|
||||
add_executable(vcd vcd.c)
|
||||
@@ -77,5 +81,5 @@ if(T_TRACER_GUI)
|
||||
|
||||
add_subdirectory(gui)
|
||||
|
||||
add_dependencies(T_tools enb gnb ue vcd to_vcd)
|
||||
add_dependencies(T_tools enb gnb gnb_mac ue vcd to_vcd)
|
||||
endif()
|
||||
|
||||
@@ -8,7 +8,7 @@ XLIBS=-lX11 -lpng -lXft
|
||||
|
||||
all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
|
||||
extract_input_subframe extract_output_subframe to_vcd extract multi \
|
||||
gnb t_tracer_app_gnb t_tracer_app_ue
|
||||
gnb t_tracer_app_gnb t_tracer_app_ue gnb_mac
|
||||
|
||||
record: utils.o record.o database.o configuration.o
|
||||
$(CC) $(CFLAGS) -o record $^ $(LIBS)
|
||||
@@ -65,14 +65,18 @@ gnb: utils.o gnb.o database.o event.o handler.o configuration.o \
|
||||
filter/filter.a
|
||||
$(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS)
|
||||
|
||||
t_tracer_app_gnb: utils.o t_tracer_app_gnb.o database.o event.o handler.o configuration.o \
|
||||
logger/logger.a filter/filter.a
|
||||
t_tracer_app_gnb: utils.o t_tracer_app_gnb.o database.o event.o handler.o \
|
||||
configuration.o logger/logger.a filter/filter.a
|
||||
$(CC) $(CFLAGS) -o t_tracer_app_gnb $^ $(LIBS) $(XLIBS)
|
||||
|
||||
t_tracer_app_ue: utils.o t_tracer_app_ue.o database.o event.o handler.o configuration.o \
|
||||
logger/logger.a filter/filter.a
|
||||
t_tracer_app_ue: utils.o t_tracer_app_ue.o database.o event.o handler.o \
|
||||
configuration.o logger/logger.a filter/filter.a
|
||||
$(CC) $(CFLAGS) -o t_tracer_app_ue $^ $(LIBS) $(XLIBS)
|
||||
|
||||
gnb_mac: gnb_mac.o gui/gui.a view/view.a logger/logger.a filter/filter.a \
|
||||
utils.o database.o configuration.o handler.o event.o
|
||||
$(CC) $(CFLAGS) -o gnb_mac $^ $(LIBS) $(XLIBS)
|
||||
|
||||
multi.o: ../incgen/T_IDs.h
|
||||
|
||||
../incgen/T_IDs.h: ../T_messages.txt
|
||||
@@ -98,7 +102,8 @@ filter/filter.a:
|
||||
clean:
|
||||
rm -f *.o core tracer_remote textlog enb ue vcd record replay
|
||||
rm -f extract_config macpdu2wireshark extract_input_subframe
|
||||
rm -f extract_output_subframe to_vcd extract multi gnb t_tracer_app_gnb t_tracer_app_ue
|
||||
rm -f extract_output_subframe to_vcd extract multi gnb
|
||||
rm -f t_tracer_app_gnb t_tracer_app_ue gnb_mac
|
||||
cd gui && $(MAKE) clean
|
||||
cd view && $(MAKE) clean
|
||||
cd logger && $(MAKE) clean
|
||||
|
||||
@@ -340,12 +340,12 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
|
||||
xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
|
||||
l = new_ttilog(h, database,
|
||||
"ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "threshold", 0);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pucch1_energy_ue_threshold_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "energy", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pucch1_energy_ue_energy_logger = l;
|
||||
|
||||
@@ -368,7 +368,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
|
||||
widget_add_child(g, line, w, -1);
|
||||
l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
|
||||
"ENB_PHY_DLSCH_UE_DCI", "mcs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->dl_mcs_logger = l;
|
||||
|
||||
@@ -379,7 +379,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
|
||||
widget_add_child(g, line, w, -1);
|
||||
l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
|
||||
"ENB_PHY_ULSCH_UE_DCI", "mcs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->ul_mcs_logger = l;
|
||||
|
||||
@@ -394,8 +394,8 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
|
||||
widget_add_child(g, col, w, -1);
|
||||
container_set_child_growable(g, col, w, 1);
|
||||
l = new_throughputlog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
|
||||
"ENB_PHY_DLSCH_UE_DCI", "TBS");
|
||||
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2);
|
||||
"ENB_PHY_DLSCH_UE_DCI", "TBS", 10);
|
||||
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 10);
|
||||
logger_add_view(l, v);
|
||||
|
||||
/* UE x UL PHY (truly: DCI) throughput */
|
||||
@@ -409,8 +409,8 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
|
||||
widget_add_child(g, col, w, -1);
|
||||
container_set_child_growable(g, col, w, 1);
|
||||
l = new_throughputlog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
|
||||
"ENB_PHY_ULSCH_UE_DCI", "TBS");
|
||||
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2);
|
||||
"ENB_PHY_ULSCH_UE_DCI", "TBS", 10);
|
||||
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 10);
|
||||
logger_add_view(l, v);
|
||||
|
||||
/* downlink/uplink UE DCIs */
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "gui/gui.h"
|
||||
#include "view/view.h"
|
||||
#include "logger/logger.h"
|
||||
#include "filter/filter.h"
|
||||
#include "database.h"
|
||||
#include "configuration.h"
|
||||
#include "handler.h"
|
||||
|
||||
typedef struct {
|
||||
int used;
|
||||
} ue_list_item;
|
||||
|
||||
typedef struct {
|
||||
widget *container;
|
||||
} gnb_gui;
|
||||
|
||||
typedef struct {
|
||||
int socket;
|
||||
gui *g;
|
||||
gnb_gui *gg;
|
||||
event_handler *h;
|
||||
void *database;
|
||||
ue_list_item ues[65536];
|
||||
int rnti_arg;
|
||||
} gnb_data;
|
||||
|
||||
void *gui_thread(void *_g)
|
||||
{
|
||||
gui *g = _g;
|
||||
gui_loop(g);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void add_ue(gnb_data *gd, int rnti, int lcid)
|
||||
{
|
||||
event_handler *h = gd->h;
|
||||
void *database = gd->database;
|
||||
gnb_gui *gg = gd->gg;
|
||||
gui *g = gd->g;
|
||||
widget *line;
|
||||
widget *w, *w2, *col;
|
||||
view *v;
|
||||
logger *l;
|
||||
|
||||
gd->ues[rnti].used = 1;
|
||||
|
||||
line = new_container(g, HORIZONTAL);
|
||||
widget_add_child(g, gg->container, line, -1);
|
||||
|
||||
/* label */
|
||||
char s[512];
|
||||
sprintf(s, "UE %d", rnti);
|
||||
widget *label = new_label(g, s);
|
||||
widget_add_child(g, line, label, -1);
|
||||
|
||||
/* DL MCS */
|
||||
w = new_xy_plot(g, 128, 55, "DL mcs", 20);
|
||||
xy_plot_set_range(g, w, 0, 1024*20, -2, 30);
|
||||
widget_add_child(g, line, w, -1);
|
||||
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
|
||||
"GNB_MAC_DL", "mcs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_DL", "rnti"),
|
||||
filter_int(rnti)));
|
||||
|
||||
/* DL TBS */
|
||||
col = new_container(g, VERTICAL);
|
||||
widget_add_child(g, line, col, -1);
|
||||
w = new_xy_plot(g, 70, 10, "DL tbs", 35);
|
||||
w2 = new_textarea(g, 70, 11, 64);
|
||||
xy_plot_set_range(g, w, 0, 1024*20, 0, 1000);
|
||||
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
|
||||
widget_add_child(g, col, w2, -1);
|
||||
widget_add_child(g, col, w, -1);
|
||||
container_set_child_growable(g, col, w, 1);
|
||||
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
|
||||
"GNB_MAC_DL", "tbs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
|
||||
view_tti_enable_automax(v, w2);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_DL", "rnti"),
|
||||
filter_int(rnti)));
|
||||
|
||||
/* DL lcid throughput */
|
||||
col = new_container(g, VERTICAL);
|
||||
widget_add_child(g, line, col, -1);
|
||||
sprintf(s, "DL lcid %d", lcid);
|
||||
w = new_xy_plot(g, 70, 10, s, 35);
|
||||
w2 = new_textarea(g, 70, 11, 64);
|
||||
xy_plot_set_range(g, w, 0, 1000, 0, 100000);
|
||||
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
|
||||
widget_add_child(g, col, w2, -1);
|
||||
widget_add_child(g, col, w, -1);
|
||||
container_set_child_growable(g, col, w, 1);
|
||||
l = new_throughputlog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
|
||||
"GNB_MAC_LCID_DL", "data_size", 20);
|
||||
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 20);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_and(
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_LCID_DL", "rnti"),
|
||||
filter_int(rnti)),
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_LCID_DL", "lcid"),
|
||||
filter_int(lcid))));
|
||||
|
||||
/* UL MCS */
|
||||
w = new_xy_plot(g, 128, 55, "UL mcs", 20);
|
||||
xy_plot_set_range(g, w, 0, 1024*20, -2, 30);
|
||||
widget_add_child(g, line, w, -1);
|
||||
/* GNB_PHY_DL_TICK (and not UL) because GNB_MAC_UL is from DCI */
|
||||
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
|
||||
"GNB_MAC_UL", "mcs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_UL", "rnti"),
|
||||
filter_int(rnti)));
|
||||
|
||||
/* UL TBS */
|
||||
col = new_container(g, VERTICAL);
|
||||
widget_add_child(g, line, col, -1);
|
||||
w = new_xy_plot(g, 70, 10, "UL tbs", 35);
|
||||
w2 = new_textarea(g, 70, 11, 64);
|
||||
xy_plot_set_range(g, w, 0, 1024*20, 0, 1000);
|
||||
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
|
||||
widget_add_child(g, col, w2, -1);
|
||||
widget_add_child(g, col, w, -1);
|
||||
container_set_child_growable(g, col, w, 1);
|
||||
/* GNB_PHY_DL_TICK (and not UL) because GNB_MAC_UL is from DCI */
|
||||
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
|
||||
"GNB_MAC_UL", "tbs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
|
||||
view_tti_enable_automax(v, w2);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_UL", "rnti"),
|
||||
filter_int(rnti)));
|
||||
|
||||
/* UL lcid throughput */
|
||||
col = new_container(g, VERTICAL);
|
||||
widget_add_child(g, line, col, -1);
|
||||
sprintf(s, "UL lcid %d", lcid);
|
||||
w = new_xy_plot(g, 70, 10, s, 35);
|
||||
w2 = new_textarea(g, 70, 11, 64);
|
||||
xy_plot_set_range(g, w, 0, 1000, 0, 100000);
|
||||
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
|
||||
widget_add_child(g, col, w2, -1);
|
||||
widget_add_child(g, col, w, -1);
|
||||
container_set_child_growable(g, col, w, 1);
|
||||
l = new_throughputlog(h, database, "GNB_PHY_UL_TICK", "frame", "slot",
|
||||
"GNB_MAC_LCID_UL", "data_size", 20);
|
||||
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 20);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_and(
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_LCID_UL", "rnti"),
|
||||
filter_int(rnti)),
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_LCID_UL", "lcid"),
|
||||
filter_int(lcid))));
|
||||
|
||||
/* lcid RLC tx buffer occupancy */
|
||||
col = new_container(g, VERTICAL);
|
||||
widget_add_child(g, line, col, -1);
|
||||
sprintf(s, "rlc tx %d", lcid);
|
||||
w = new_xy_plot(g, 70, 10, s, 35);
|
||||
w2 = new_textarea(g, 70, 11, 64);
|
||||
xy_plot_set_range(g, w, 0, 1024*20, 0, 1000);
|
||||
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
|
||||
widget_add_child(g, col, w2, -1);
|
||||
widget_add_child(g, col, w, -1);
|
||||
container_set_child_growable(g, col, w, 1);
|
||||
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
|
||||
"GNB_MAC_LCID_DL", "tx_list_occupancy", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
|
||||
view_tti_enable_automax(v, w2);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_and(
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_LCID_DL", "rnti"),
|
||||
filter_int(rnti)),
|
||||
filter_eq(
|
||||
filter_evarg(database, "GNB_MAC_LCID_DL", "lcid"),
|
||||
filter_int(lcid))));
|
||||
}
|
||||
|
||||
void build_gui(gnb_gui *gg, gui *g)
|
||||
{
|
||||
widget *main_window;
|
||||
|
||||
main_window = new_toplevel_window(g, 900, 1000, "gNB MAC tracer");
|
||||
gg->container = new_container(g, VERTICAL);
|
||||
widget_add_child(g, main_window, gg->container, -1);
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf(
|
||||
"options:\n"
|
||||
" -d <database file> this option is mandatory\n"
|
||||
" -ip <host> connect to given IP address (default %s)\n"
|
||||
" -p <port> connect to given port (default %d)\n",
|
||||
DEFAULT_REMOTE_IP,
|
||||
DEFAULT_REMOTE_PORT
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void check_new_ue(void *_gd, event e)
|
||||
{
|
||||
gnb_data *gd = _gd;
|
||||
int rnti = e.e[gd->rnti_arg].i;
|
||||
if (!gd->ues[rnti].used)
|
||||
add_ue(gd, rnti, 4);
|
||||
}
|
||||
|
||||
int main(int n, char **v)
|
||||
{
|
||||
gui *g;
|
||||
gnb_gui gg;
|
||||
gnb_data *gd;
|
||||
char *database_filename = NULL;
|
||||
void *database;
|
||||
char *ip = DEFAULT_REMOTE_IP;
|
||||
int port = DEFAULT_REMOTE_PORT;
|
||||
event_handler *h;
|
||||
int *is_on;
|
||||
int number_of_events;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < n; i++) {
|
||||
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
|
||||
if (!strcmp(v[i], "-d")) { if (i > n-2) usage(); database_filename = v[++i]; continue; }
|
||||
if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
|
||||
if (!strcmp(v[i], "-p")) { if (i > n-2) usage(); port = atoi(v[++i]); continue; }
|
||||
usage();
|
||||
}
|
||||
|
||||
if (database_filename == NULL) {
|
||||
printf("ERROR: provide a database file (-d)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
database = parse_database(database_filename);
|
||||
|
||||
load_config_file(database_filename);
|
||||
|
||||
number_of_events = number_of_ids(database);
|
||||
is_on = calloc(number_of_events, sizeof(int));
|
||||
if (is_on == NULL) abort();
|
||||
|
||||
on_off(database, "GNB_PHY_DL_TICK", is_on, 1);
|
||||
on_off(database, "GNB_MAC_DL", is_on, 1);
|
||||
on_off(database, "GNB_MAC_LCID_DL", is_on, 1);
|
||||
on_off(database, "GNB_PHY_UL_TICK", is_on, 1);
|
||||
on_off(database, "GNB_MAC_UL", is_on, 1);
|
||||
on_off(database, "GNB_MAC_LCID_UL", is_on, 1);
|
||||
|
||||
gd = calloc(1, sizeof(*gd)); if (!gd) abort();
|
||||
|
||||
h = new_handler(database);
|
||||
|
||||
g = gui_init();
|
||||
new_thread(gui_thread, g);
|
||||
|
||||
build_gui(&gg, g);
|
||||
|
||||
gd->g = g;
|
||||
gd->gg = ≫
|
||||
gd->h = h;
|
||||
gd->database = database;
|
||||
|
||||
/* get rnti_arg from event GNB_MAC_DL */
|
||||
int event_id = event_id_from_name(database, "GNB_MAC_DL");
|
||||
database_event_format f = get_format(database, event_id);
|
||||
gd->rnti_arg = -1;
|
||||
for (i = 0; i < f.count; i++) {
|
||||
if (!strcmp(f.name[i], "rnti")) gd->rnti_arg = i;
|
||||
}
|
||||
if (gd->rnti_arg == -1) {
|
||||
printf("fatal: event 'GNB_MAC_DL' does not have argument 'rnti'\n");
|
||||
exit(1);
|
||||
}
|
||||
if (strcmp(f.type[gd->rnti_arg], "int") != 0) {
|
||||
printf("fatal: argument 'rnti' of event 'GNB_MAC_DL' is not 'int'\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
register_handler_function(h, event_id, check_new_ue, gd);
|
||||
|
||||
OBUF ebuf = {.osize = 0, .omaxsize = 0, .obuf = NULL};
|
||||
|
||||
gd->socket = -1;
|
||||
|
||||
restart:
|
||||
clear_remote_config();
|
||||
if (gd->socket != -1) close(gd->socket);
|
||||
gd->socket = connect_to(ip, port);
|
||||
|
||||
/* send the first message - activate selected traces */
|
||||
int t = 1;
|
||||
if (socket_send(gd->socket, &t, 1) == -1 ||
|
||||
socket_send(gd->socket, &number_of_events, sizeof(int)) == -1 ||
|
||||
socket_send(gd->socket, is_on, number_of_events * sizeof(int)) == -1)
|
||||
goto restart;
|
||||
|
||||
while (1) {
|
||||
event e;
|
||||
e = get_event(gd->socket, &ebuf, database);
|
||||
if (e.type == -1) goto restart;
|
||||
handle_event(h, e);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -54,6 +54,8 @@ void container_set_child_growable(gui *_gui, widget *_this,
|
||||
int xy_plot_new_plot(gui *gui, widget *this, int color);
|
||||
void xy_plot_set_range(gui *gui, widget *this,
|
||||
float xmin, float xmax, float ymin, float ymax);
|
||||
void xy_plot_get_range(gui *gui, widget *this,
|
||||
float *xmin, float *xmax, float *ymin, float *ymax);
|
||||
void xy_plot_set_points(gui *gui, widget *this,
|
||||
int plot, int npoints, float *x, float *y);
|
||||
void xy_plot_get_dimensions(gui *gui, widget *this, int *width, int *height);
|
||||
|
||||
@@ -280,6 +280,22 @@ void xy_plot_set_range(gui *_gui, widget *_this,
|
||||
gunlock(g);
|
||||
}
|
||||
|
||||
void xy_plot_get_range(gui *_gui, widget *_this,
|
||||
float *xmin, float *xmax, float *ymin, float *ymax)
|
||||
{
|
||||
struct gui *g = _gui;
|
||||
struct xy_plot_widget *this = _this;
|
||||
|
||||
glock(g);
|
||||
|
||||
*xmin = this->xmin;
|
||||
*xmax = this->xmax;
|
||||
*ymin = this->ymin;
|
||||
*ymax = this->ymax;
|
||||
|
||||
gunlock(g);
|
||||
}
|
||||
|
||||
void xy_plot_set_points(gui *_gui, widget *_this, int plot,
|
||||
int npoints, float *x, float *y)
|
||||
{
|
||||
|
||||
@@ -15,8 +15,8 @@ logger *new_ticked_ttilog(void *event_handler, void *database,
|
||||
char *event_name, char *data_varname,
|
||||
int convert_to_dB, float empty_value);
|
||||
logger *new_throughputlog(void *event_handler, void *database,
|
||||
char *tick_event_name, char *frame_varname, char *subframe_varname,
|
||||
char *event_name, char *data_varname);
|
||||
char *tick_event_name, char *frame_varname, char *tick_varname,
|
||||
char *event_name, char *data_varname, int ticks_per_frame);
|
||||
logger *new_timelog(void *event_handler, void *database, char *event_name);
|
||||
logger *new_ticklog(void *event_handler, void *database,
|
||||
char *event_name, char *frame_name, char *subframe_name);
|
||||
|
||||
@@ -13,13 +13,14 @@ struct throughputlog {
|
||||
struct logger common;
|
||||
void *database;
|
||||
int tick_frame_arg;
|
||||
int tick_subframe_arg;
|
||||
int tick_tick_arg;
|
||||
int data_frame_arg;
|
||||
int data_subframe_arg;
|
||||
int data_tick_arg;
|
||||
int data_arg;
|
||||
int last_tick_frame;
|
||||
int last_tick_subframe;
|
||||
unsigned long bits[1000];
|
||||
int last_tick_tick;
|
||||
int ticks_per_frame;
|
||||
unsigned long *bits;
|
||||
unsigned long total;
|
||||
int insert_point;
|
||||
char *tick_event_name;
|
||||
@@ -32,16 +33,16 @@ static void _event(void *p, event e)
|
||||
{
|
||||
struct throughputlog *l = p;
|
||||
int frame;
|
||||
int subframe;
|
||||
int tick;
|
||||
unsigned long value;
|
||||
|
||||
if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0)
|
||||
return;
|
||||
|
||||
frame = e.e[l->data_frame_arg].i;
|
||||
subframe = e.e[l->data_subframe_arg].i;
|
||||
tick = e.e[l->data_tick_arg].i;
|
||||
|
||||
if (frame != l->last_tick_frame || subframe != l->last_tick_subframe) {
|
||||
if (frame != l->last_tick_frame || tick != l->last_tick_tick) {
|
||||
printf("WARNING: %s:%d: data comes without previous tick!\n",
|
||||
__FILE__, __LINE__);
|
||||
return;
|
||||
@@ -62,28 +63,34 @@ static void _tick_event(void *p, event e)
|
||||
struct throughputlog *l = p;
|
||||
int i;
|
||||
int frame;
|
||||
int subframe;
|
||||
int tick;
|
||||
|
||||
if (l->tick_filter != NULL && filter_eval(l->tick_filter, e) == 0)
|
||||
return;
|
||||
|
||||
frame = e.e[l->tick_frame_arg].i;
|
||||
subframe = e.e[l->tick_subframe_arg].i;
|
||||
tick = e.e[l->tick_tick_arg].i;
|
||||
|
||||
for (i = 0; i < l->common.vsize; i++)
|
||||
l->common.v[i]->append(l->common.v[i], frame, subframe, (double)l->total);
|
||||
l->common.v[i]->append(l->common.v[i], frame, tick, (double)l->total);
|
||||
|
||||
l->insert_point = (l->insert_point + 1) % 1000;
|
||||
l->total -= l->bits[l->insert_point];
|
||||
l->bits[l->insert_point] = 0;
|
||||
while (l->last_tick_frame != frame || l->last_tick_tick != tick) {
|
||||
l->insert_point = (l->insert_point + 1) % (100 * l->ticks_per_frame);
|
||||
l->total -= l->bits[l->insert_point];
|
||||
l->bits[l->insert_point] = 0;
|
||||
l->last_tick_tick++;
|
||||
if (l->last_tick_tick == l->ticks_per_frame) {
|
||||
l->last_tick_tick = 0;
|
||||
l->last_tick_frame++;
|
||||
l->last_tick_frame %= 1024;
|
||||
}
|
||||
}
|
||||
|
||||
l->last_tick_frame = frame;
|
||||
l->last_tick_subframe = subframe;
|
||||
}
|
||||
|
||||
logger *new_throughputlog(event_handler *h, void *database,
|
||||
char *tick_event_name, char *frame_varname, char *subframe_varname,
|
||||
char *event_name, char *data_varname)
|
||||
char *tick_event_name, char *frame_varname, char *tick_varname,
|
||||
char *event_name, char *data_varname, int ticks_per_frame)
|
||||
{
|
||||
struct throughputlog *ret;
|
||||
int event_id;
|
||||
@@ -106,21 +113,21 @@ logger *new_throughputlog(event_handler *h, void *database,
|
||||
|
||||
f = get_format(database, event_id);
|
||||
|
||||
/* look for frame and subframe */
|
||||
/* look for frame and tick */
|
||||
ret->tick_frame_arg = -1;
|
||||
ret->tick_subframe_arg = -1;
|
||||
ret->tick_tick_arg = -1;
|
||||
for (i = 0; i < f.count; i++) {
|
||||
if (!strcmp(f.name[i], frame_varname)) ret->tick_frame_arg = i;
|
||||
if (!strcmp(f.name[i], subframe_varname)) ret->tick_subframe_arg = i;
|
||||
if (!strcmp(f.name[i], tick_varname)) ret->tick_tick_arg = i;
|
||||
}
|
||||
if (ret->tick_frame_arg == -1) {
|
||||
printf("%s:%d: frame argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, frame_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (ret->tick_subframe_arg == -1) {
|
||||
printf("%s:%d: subframe argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, subframe_varname, event_name);
|
||||
if (ret->tick_tick_arg == -1) {
|
||||
printf("%s:%d: tick argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, tick_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->tick_frame_arg], "int") != 0) {
|
||||
@@ -128,9 +135,9 @@ logger *new_throughputlog(event_handler *h, void *database,
|
||||
__FILE__, __LINE__, frame_varname);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->tick_subframe_arg], "int") != 0) {
|
||||
if (strcmp(f.type[ret->tick_tick_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, subframe_varname);
|
||||
__FILE__, __LINE__, tick_varname);
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -141,13 +148,13 @@ logger *new_throughputlog(event_handler *h, void *database,
|
||||
|
||||
f = get_format(database, event_id);
|
||||
|
||||
/* look for frame, subframe and data args */
|
||||
/* look for frame, tick and data args */
|
||||
ret->data_frame_arg = -1;
|
||||
ret->data_subframe_arg = -1;
|
||||
ret->data_tick_arg = -1;
|
||||
ret->data_arg = -1;
|
||||
for (i = 0; i < f.count; i++) {
|
||||
if (!strcmp(f.name[i], frame_varname)) ret->data_frame_arg = i;
|
||||
if (!strcmp(f.name[i], subframe_varname)) ret->data_subframe_arg = i;
|
||||
if (!strcmp(f.name[i], tick_varname)) ret->data_tick_arg = i;
|
||||
if (!strcmp(f.name[i], data_varname)) ret->data_arg = i;
|
||||
}
|
||||
if (ret->data_frame_arg == -1) {
|
||||
@@ -155,9 +162,9 @@ logger *new_throughputlog(event_handler *h, void *database,
|
||||
__FILE__, __LINE__, frame_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (ret->data_subframe_arg == -1) {
|
||||
printf("%s:%d: subframe argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, subframe_varname, event_name);
|
||||
if (ret->data_tick_arg == -1) {
|
||||
printf("%s:%d: tick argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, tick_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (ret->data_arg == -1) {
|
||||
@@ -170,9 +177,9 @@ logger *new_throughputlog(event_handler *h, void *database,
|
||||
__FILE__, __LINE__, frame_varname);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->data_subframe_arg], "int") != 0) {
|
||||
if (strcmp(f.type[ret->data_tick_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, subframe_varname);
|
||||
__FILE__, __LINE__, tick_varname);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->data_arg], "int") != 0 &&
|
||||
@@ -183,6 +190,10 @@ logger *new_throughputlog(event_handler *h, void *database,
|
||||
abort();
|
||||
}
|
||||
|
||||
ret->ticks_per_frame = ticks_per_frame;
|
||||
ret->bits = calloc(100 * ticks_per_frame, sizeof(unsigned long));
|
||||
if (ret->bits == NULL) abort();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+17
-17
@@ -250,15 +250,15 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
|
||||
widget_add_child(g, line, w, -1);
|
||||
xy_plot_set_range(g, w, 0, 1024*10, -130, 35);
|
||||
/*l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rssi", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#720c0c"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->phy_meas_logger = l;*/
|
||||
l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rsrp", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->phy_meas_logger = l;
|
||||
l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "snr", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c720c"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c720c"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->phy_meas_logger = l;
|
||||
|
||||
@@ -277,7 +277,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
|
||||
widget_add_child(g, line, w, -1);
|
||||
l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe",
|
||||
"UE_PHY_DLSCH_UE_DCI", "mcs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->dl_mcs_logger = l;
|
||||
|
||||
@@ -288,7 +288,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
|
||||
widget_add_child(g, line, w, -1);
|
||||
l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe",
|
||||
"UE_PHY_ULSCH_UE_DCI", "mcs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->ul_mcs_logger = l;
|
||||
|
||||
@@ -301,12 +301,12 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
|
||||
xy_plot_set_range(g, w, 0, 1024*10, -30, 50);
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "p0_pusch", 0);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pusch_power_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "ampl", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#720c0c"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pusch_ampl_logger = l;
|
||||
|
||||
@@ -319,12 +319,12 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
|
||||
xy_plot_set_range(g, w, 0, 1024*10, -30, 50);
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "p0_pucch", 0);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pucch_power_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "ampl", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#720c0c"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pucch_ampl_logger = l;
|
||||
|
||||
@@ -335,22 +335,22 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
|
||||
xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level00", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pdsch_energy_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level01", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#00ff00"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#00ff00"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pdsch_energy_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level10", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pdsch_energy_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level11", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0000ff"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0000ff"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pdsch_energy_logger = l;
|
||||
|
||||
@@ -361,22 +361,22 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
|
||||
xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level00", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pdcch_energy_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level01", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#00ff00"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#00ff00"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pdcch_energy_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level10", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pdcch_energy_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level11", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0000ff"));
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0000ff"), 10);
|
||||
logger_add_view(l, v);
|
||||
e->pdcch_energy_logger = l;
|
||||
|
||||
|
||||
@@ -15,11 +15,14 @@ struct scrolltti {
|
||||
int plot;
|
||||
float refresh_rate;
|
||||
pthread_mutex_t lock;
|
||||
unsigned long data[1000];
|
||||
unsigned long total; /* sum data[0..999] to have smoother value printed */
|
||||
float xout[1000];
|
||||
float yout[1000];
|
||||
int ticks_per_frame;
|
||||
unsigned long *data;
|
||||
unsigned long total; /* sum data[0..n] to have smoother value printed */
|
||||
float *xout;
|
||||
float *yout;
|
||||
int insert_point;
|
||||
int next_tick_frame;
|
||||
int next_tick_tick;
|
||||
};
|
||||
|
||||
/* this array is used to get Y range 1000, 2000, 5000, 10000, ... */
|
||||
@@ -38,21 +41,21 @@ static void *scrolltti_thread(void *_this)
|
||||
/* TODO: optimize */
|
||||
p = this->insert_point;
|
||||
max = 0;
|
||||
for (i = 0; i < 1000; i++) {
|
||||
for (i = 0; i < this->ticks_per_frame * 100; i++) {
|
||||
this->xout[i] = i;
|
||||
this->yout[i] = this->data[p];
|
||||
if (this->data[p] > max) max = this->data[p];
|
||||
p = (p + 1) % 1000;
|
||||
p = (p + 1) % (this->ticks_per_frame * 100);
|
||||
}
|
||||
bps(o, this->total/1000., "b/s");
|
||||
bps(o, this->total/(this->ticks_per_frame * 100.), "b/s");
|
||||
textarea_set_text(this->g, this->throughput_textarea, o);
|
||||
/* for Y range we want 1000, 2000, 5000, 10000, 20000, 50000, etc. */
|
||||
if (max < 1000) max = 1000;
|
||||
mlog = pow(10, floor(log10(max)));
|
||||
max = tolog[(int)ceil(max/mlog)] * mlog;
|
||||
xy_plot_set_range(this->g, this->w, 0, 1000, 0, max);
|
||||
xy_plot_set_range(this->g, this->w, 0, this->ticks_per_frame * 100, 0, max);
|
||||
xy_plot_set_points(this->g, this->w, this->plot,
|
||||
1000, this->xout, this->yout);
|
||||
this->ticks_per_frame * 100, this->xout, this->yout);
|
||||
if (pthread_mutex_unlock(&this->lock)) abort();
|
||||
sleepms(1000/this->refresh_rate);
|
||||
}
|
||||
@@ -65,20 +68,40 @@ static void clear(view *this)
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void append(view *_this, int frame, int subframe, double value)
|
||||
static void insert(struct scrolltti *this, double value)
|
||||
{
|
||||
this->total -= this->data[this->insert_point];
|
||||
this->data[this->insert_point] = value;
|
||||
this->total += this->data[this->insert_point];
|
||||
this->insert_point = (this->insert_point + 1) % (this->ticks_per_frame * 100);
|
||||
}
|
||||
|
||||
static void next_tick(struct scrolltti *this)
|
||||
{
|
||||
this->next_tick_tick++;
|
||||
if (this->next_tick_tick == this->ticks_per_frame) {
|
||||
this->next_tick_tick = 0;
|
||||
this->next_tick_frame++;
|
||||
this->next_tick_frame %= 1024;
|
||||
}
|
||||
}
|
||||
|
||||
static void append(view *_this, int frame, int tick, double value)
|
||||
{
|
||||
struct scrolltti *this = (struct scrolltti *)_this;
|
||||
|
||||
if (pthread_mutex_lock(&this->lock)) abort();
|
||||
this->total -= this->data[this->insert_point];
|
||||
this->data[this->insert_point] = value;
|
||||
this->total += this->data[this->insert_point];
|
||||
this->insert_point = (this->insert_point + 1) % 1000;
|
||||
while (this->next_tick_frame != frame || this->next_tick_tick != tick) {
|
||||
insert(this, 0);
|
||||
next_tick(this);
|
||||
}
|
||||
insert(this, value);
|
||||
next_tick(this);
|
||||
if (pthread_mutex_unlock(&this->lock)) abort();
|
||||
}
|
||||
|
||||
view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color,
|
||||
widget *throughput_textarea)
|
||||
widget *throughput_textarea, int ticks_per_frame)
|
||||
{
|
||||
struct scrolltti *ret = calloc(1, sizeof(struct scrolltti));
|
||||
if (ret == NULL) abort();
|
||||
@@ -92,6 +115,14 @@ view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color,
|
||||
ret->throughput_textarea = throughput_textarea;
|
||||
ret->plot = xy_plot_new_plot(g, w, color);
|
||||
|
||||
ret->ticks_per_frame = ticks_per_frame;
|
||||
ret->data = calloc(ticks_per_frame * 100, sizeof(unsigned long));
|
||||
if (ret->data == NULL) abort();
|
||||
ret->xout = calloc(ticks_per_frame * 100, sizeof(float));
|
||||
if (ret->xout == NULL) abort();
|
||||
ret->yout = calloc(ticks_per_frame * 100, sizeof(float));
|
||||
if (ret->yout == NULL) abort();
|
||||
|
||||
if (pthread_mutex_init(&ret->lock, NULL)) abort();
|
||||
|
||||
new_thread(scrolltti_thread, ret);
|
||||
|
||||
@@ -5,31 +5,36 @@
|
||||
#include <pthread.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
struct tti {
|
||||
view common;
|
||||
gui *g;
|
||||
widget *w;
|
||||
int automax;
|
||||
widget *w2;
|
||||
int plot;
|
||||
float refresh_rate;
|
||||
pthread_mutex_t lock;
|
||||
float data[1024*10];
|
||||
int valid[1024*10];
|
||||
float xout[1024*10];
|
||||
float yout[1024*10];
|
||||
float *data;
|
||||
int *valid;
|
||||
float *xout;
|
||||
float *yout;
|
||||
int last_insert_point;
|
||||
int ticks_per_frame;
|
||||
};
|
||||
|
||||
static int far_enough(int i, int last_insert, int plot_width)
|
||||
static int far_enough(int i, int last_insert, int plot_width,
|
||||
int ticks_per_frame)
|
||||
{
|
||||
int p1;
|
||||
int p2;
|
||||
int hole_size_px;
|
||||
int hole_size_tti;
|
||||
hole_size_px = 10;
|
||||
hole_size_tti = 10240 * hole_size_px / plot_width;
|
||||
hole_size_tti = 1024 * ticks_per_frame * hole_size_px / plot_width;
|
||||
p1 = last_insert;
|
||||
p2 = (last_insert + hole_size_tti) % (1024*10);
|
||||
p2 = (last_insert + hole_size_tti) % (1024 * ticks_per_frame);
|
||||
if (p1 < p2) {
|
||||
return !(i > p1 && i < p2);
|
||||
}
|
||||
@@ -48,15 +53,31 @@ static void *tti_thread(void *_this)
|
||||
if (pthread_mutex_lock(&this->lock)) abort();
|
||||
xy_plot_get_dimensions(this->g, this->w, &plot_width, &plot_height);
|
||||
length = 0;
|
||||
double max = 0;
|
||||
/* TODO: optimize */
|
||||
for (i = 0; i < 1024*10; i++)
|
||||
for (i = 0; i < 1024 * this->ticks_per_frame; i++)
|
||||
/* do not take points too close after last insertion point */
|
||||
if (this->valid[i] &&
|
||||
far_enough(i, this->last_insert_point, plot_width)) {
|
||||
far_enough(i, this->last_insert_point, plot_width,
|
||||
this->ticks_per_frame)) {
|
||||
this->xout[length] = i;
|
||||
this->yout[length] = this->data[i];
|
||||
if (this->data[i] > max) max = this->data[i];
|
||||
length++;
|
||||
}
|
||||
if (this->automax) {
|
||||
char o[128];
|
||||
sprintf(o, "%d", (int)max);
|
||||
textarea_set_text(this->g, this->w2, o);
|
||||
/* for Y range we want 10, 20, 50, 100, 200, 500, etc. */
|
||||
if (max < 10) max = 10;
|
||||
double mlog = pow(10, floor(log10(max)));
|
||||
static int tolog[11] = { -1, 1, 2, 5, 5, 5, 10, 10, 10, 10, 10 };
|
||||
max = tolog[(int)ceil(max/mlog)] * mlog;
|
||||
float xmin, xmax, ymin, ymax;
|
||||
xy_plot_get_range(this->g, this->w, &xmin, &xmax, &ymin, &ymax);
|
||||
xy_plot_set_range(this->g, this->w, xmin, xmax, 0, max);
|
||||
}
|
||||
xy_plot_set_points(this->g, this->w, this->plot,
|
||||
length, this->xout, this->yout);
|
||||
if (pthread_mutex_unlock(&this->lock)) abort();
|
||||
@@ -71,11 +92,11 @@ static void clear(view *this)
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void append(view *_this, int frame, int subframe, double value)
|
||||
static void append(view *_this, int frame, int tick, double value)
|
||||
{
|
||||
struct tti *this = (struct tti *)_this;
|
||||
int i;
|
||||
int index = frame * 10 + subframe;
|
||||
int index = frame * this->ticks_per_frame + tick;
|
||||
|
||||
if (pthread_mutex_lock(&this->lock)) abort();
|
||||
|
||||
@@ -84,10 +105,10 @@ static void append(view *_this, int frame, int subframe, double value)
|
||||
* this may be wrong if delay between two append is
|
||||
* greater than 1024 frames (something like that)
|
||||
*/
|
||||
i = (this->last_insert_point + 1) % (1024*10);
|
||||
i = (this->last_insert_point + 1) % (1024 * this->ticks_per_frame);
|
||||
while (i != index) {
|
||||
this->valid[i] = 0;
|
||||
i = (i + 1) % (1024*10);
|
||||
i = (i + 1) % (1024 * this->ticks_per_frame);
|
||||
}
|
||||
|
||||
this->data[index] = value;
|
||||
@@ -98,7 +119,8 @@ static void append(view *_this, int frame, int subframe, double value)
|
||||
if (pthread_mutex_unlock(&this->lock)) abort();
|
||||
}
|
||||
|
||||
view *new_view_tti(float refresh_rate, gui *g, widget *w, int color)
|
||||
view *new_view_tti(float refresh_rate, gui *g, widget *w, int color,
|
||||
int ticks_per_frame)
|
||||
{
|
||||
struct tti *ret = calloc(1, sizeof(struct tti));
|
||||
if (ret == NULL) abort();
|
||||
@@ -115,7 +137,24 @@ view *new_view_tti(float refresh_rate, gui *g, widget *w, int color)
|
||||
|
||||
if (pthread_mutex_init(&ret->lock, NULL)) abort();
|
||||
|
||||
ret->ticks_per_frame = ticks_per_frame;
|
||||
ret->data = calloc(ticks_per_frame * 1024, sizeof(float));
|
||||
if (ret->data == NULL) abort();
|
||||
ret->valid = calloc(ticks_per_frame * 1024, sizeof(int));
|
||||
if (ret->valid == NULL) abort();
|
||||
ret->xout = calloc(ticks_per_frame * 1024, sizeof(float));
|
||||
if (ret->xout == NULL) abort();
|
||||
ret->yout = calloc(ticks_per_frame * 1024, sizeof(float));
|
||||
if (ret->yout == NULL) abort();
|
||||
|
||||
new_thread(tti_thread, ret);
|
||||
|
||||
return (view *)ret;
|
||||
}
|
||||
|
||||
void view_tti_enable_automax(view *_tti, widget *w2)
|
||||
{
|
||||
struct tti *tti = (struct tti *)_tti;
|
||||
tti->automax = 1;
|
||||
tti->w2 = w2;
|
||||
}
|
||||
|
||||
@@ -17,15 +17,16 @@ view *new_view_stdout(void);
|
||||
view *new_view_textlist(int maxsize, float refresh_rate, gui *g, widget *w);
|
||||
view *new_view_xy(int length, float refresh_rate, gui *g, widget *w,
|
||||
int color, enum xy_mode mode);
|
||||
view *new_view_tti(float refresh_rate, gui *g, widget *w,
|
||||
int color);
|
||||
view *new_view_tti(float refresh_rate, gui *g, widget *w, int color,
|
||||
int ticks_per_frame);
|
||||
view *new_view_scrolltti(float refresh_rate, gui *g, widget *w,
|
||||
int color, widget *throughput_label);
|
||||
int color, widget *throughput_label, int ticks_per_frame);
|
||||
view *new_view_time(int number_of_seconds, float refresh_rate,
|
||||
gui *g, widget *w);
|
||||
view *new_subview_time(view *time, int line, int color, int size);
|
||||
view *new_view_ticktime(float refresh_rate, gui *g, widget *w);
|
||||
view *new_subview_ticktime(view *ticktime, int line, int color, int size);
|
||||
void ticktime_set_tick(view *ticktime, void *logger);
|
||||
void view_tti_enable_automax(view *tti, widget *w2);
|
||||
|
||||
#endif /* _VIEW_H_ */
|
||||
|
||||
@@ -1465,13 +1465,13 @@ frequency_range_t get_freq_range_from_band(uint16_t band)
|
||||
return band <= 256 ? FR1 : FR2;
|
||||
}
|
||||
|
||||
float get_beta_dmrs_pusch(int num_cdm_groups_no_data, pusch_dmrs_type_t dmrs_type)
|
||||
float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2)
|
||||
{
|
||||
float beta_dmrs_pusch = 1.0;
|
||||
if (num_cdm_groups_no_data == 2) {
|
||||
beta_dmrs_pusch = powf(10.0, 3.0 / 20.0);
|
||||
} else if (num_cdm_groups_no_data == 3) {
|
||||
if (dmrs_type == pusch_dmrs_type2)
|
||||
if (is_type2)
|
||||
beta_dmrs_pusch = powf(10.0, 4.77 / 20.0);
|
||||
}
|
||||
return beta_dmrs_pusch;
|
||||
|
||||
@@ -320,15 +320,15 @@ frequency_range_t get_freq_range_from_arfcn(uint32_t arfcn);
|
||||
frequency_range_t get_freq_range_from_band(uint16_t band);
|
||||
|
||||
/**
|
||||
* @brief Calculates the scaling factor for the ratio of PUSCH EPRE to DMRS EPRE.
|
||||
* @brief Calculates the scaling factor for the ratio of PUSCH/PDSCH EPRE to DMRS EPRE.
|
||||
*
|
||||
* @param num_cdm_groups_no_data The number of CDM groups without data.
|
||||
* @param dmrs_type The DMRS type.
|
||||
* @return The calculated beta scaling factor for the ratio of PUSCH EPRE to DMRS EPRE.
|
||||
* @param is_type2 true if calculating for DMRS configuration type 2
|
||||
* @return The calculated beta scaling factor for the ratio of PUSCH/PDSCH EPRE to DMRS EPRE.
|
||||
*
|
||||
* @note The values are derived from TS 38.214 Table 6.2.2-1.
|
||||
* @note The values are the same for PUSCH and PDSCH and are derived from TS 38.214 Table 6.2.2-1./4.1-1
|
||||
*/
|
||||
float get_beta_dmrs_pusch(int num_cdm_groups_no_data, pusch_dmrs_type_t dmrs_type);
|
||||
float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2);
|
||||
|
||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||
|
||||
@@ -62,7 +62,7 @@ add_dependencies(telnetsrv telnetsrv_ci)
|
||||
|
||||
message(STATUS "Add CI specific telnet functions for nrUE in telnetsrv_ciUE.so")
|
||||
add_library(telnetsrv_ciUE MODULE telnetsrv_ciUE.c)
|
||||
target_link_libraries(telnetsrv_ciUE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
target_link_libraries(telnetsrv_ciUE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL)
|
||||
add_dependencies(telnetsrv telnetsrv_ciUE)
|
||||
|
||||
message(STATUS "Add bearer specific telnet functions in libtelnetsrv_bearer.so")
|
||||
|
||||
+224
-32
@@ -1235,7 +1235,13 @@ You should be able to connect a UE now.
|
||||
|
||||
|
||||
# OAI Management Plane
|
||||
We support Configuration Management in OAI gNB, where gNB configures CU-planes, interfaces, TX/RX antennas, and TX/RX carriers for the RU.
|
||||
In OAI gNB, we support:
|
||||
* Configuration Management: interface(s) creation, configuration of RU CU-planes, Tx/Rx antennas, and Tx/Rx carriers.
|
||||
* Performance Management: activation/deactivation of available RU performance measurements and its notification reception with 10s periodicity:
|
||||
```bash
|
||||
[HW] [MPLANE] [PM: "192.168.80.9"][RX_ON_TIME 773428][RX_EARLY 0][RX_LATE 0][RX_TOTAL 878881][RX_ON_TIME_C 104744][RX_EARLY_C 0][RX_LATE_C 0][TX_TOTAL 435922]
|
||||
```
|
||||
|
||||
The reference specifications:
|
||||
* `O-RAN.WG4.MP.0-v05.00`
|
||||
* `O-RAN.WG4.MP-YANGs-v04.00`
|
||||
@@ -1375,7 +1381,7 @@ Once the mplane service is successfully enabled on the RU, two new users are bei
|
||||
oranbenetel:x:1000:1000::/home/oranbenetel:/bin/sh
|
||||
oranext:x:1001:1001::/home/oranext:/bin/sh
|
||||
```
|
||||
Create `oranbenetel` home directory:
|
||||
OAI gNB requires the `sudo` access group for NETCONF session. In the case of Benetel O-RUs, the corresponding user is `oranbenetel`. Therefore, please create its home directory:
|
||||
```bash
|
||||
mkdir /home/oranbenetel && chown oranbenetel:oranbenetel /home/oranbenetel
|
||||
```
|
||||
@@ -1393,7 +1399,7 @@ The reference gNB configuration file for one Benetel RAN550:
|
||||
The reference DU configuration file for two Benetel RAN650:
|
||||
[gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf)
|
||||
|
||||
In order to run gNB/DU with M-plane, we need to modify the `fhi_72` section in the configuration file.
|
||||
In order to run gNB/DU with M-plane, we need to modify Tx gain `att_tx` in RU section, as well as the `fhi_72` section in the configuration file.
|
||||
Example for one RU:
|
||||
```bash
|
||||
fhi_72 = {
|
||||
@@ -1404,6 +1410,7 @@ fhi_72 = {
|
||||
du_key_pair = ("<path-to>/.ssh/id_rsa.pub", "<path-to>/.ssh/id_rsa");
|
||||
du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67"); # only one needed if one VF configured
|
||||
vlan_tag = (9, 9); # only one needed if one VF configured
|
||||
ru_username = ("oranbenetel");
|
||||
ru_ip_addr = ("192.168.80.9");
|
||||
fh_config = ({
|
||||
T1a_cp_dl = (419, 470);
|
||||
@@ -1423,6 +1430,7 @@ fhi_72 = {
|
||||
du_key_pair = ("/home/oaicicd/.ssh/id_rsa.pub", "/home/oaicicd/.ssh/id_rsa");
|
||||
du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67", "00:11:22:33:44:68", "00:11:22:33:44:69"); # only two needed if two VFs configured
|
||||
vlan_tag = (9, 9, 11, 11); # only two needed if two VFs configured
|
||||
ru_username = ("oranbenetel", "oranbenetel");
|
||||
ru_ip_addr = ("192.168.80.9", "192.168.80.10");
|
||||
fh_config = (
|
||||
# RAN550 #1
|
||||
@@ -1451,6 +1459,7 @@ fhi_72 = {
|
||||
* `du_key_pair`: ssh public and private keys to authenticate RU with NETCONF
|
||||
* `du_addr`: DU MAC address(es) to create CU-plane interface(s) in the RU
|
||||
* `vlan_tag`: VLAN U and C plane tags to create CU-plane interface(s) in the RU
|
||||
* `ru_username`: Username with `sudo` access to connect to the RU via M-plane
|
||||
* `ru_ip_addr`: RU IP address to connect to the RU via M-plane
|
||||
* `dpdk_mem_size`: [*]
|
||||
* `dpdk_iova_mode`: [*]
|
||||
@@ -1557,7 +1566,9 @@ sequenceDiagram
|
||||
|
||||
note over du: DU configures xran
|
||||
|
||||
du->ru: 12. DU and RU exchange packets
|
||||
du->ru: 12. DU activates Performance Measurements
|
||||
|
||||
du->ru: 13. DU and RU exchange packets
|
||||
```
|
||||
|
||||
|
||||
@@ -1596,7 +1607,9 @@ sequenceDiagram
|
||||
Band sector ID 0
|
||||
CC ID 0
|
||||
RU port ID 0
|
||||
max Tx gain 24.0
|
||||
[HW] [MPLANE] Successfully retrieved all the U-plane info - interface name, TX/RX carrier names, and TX/RX endpoint names.
|
||||
[HW] [MPLANE] Successfully retreived all performance measurement names.
|
||||
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <get-schema> for module "ietf-yang-metadata".
|
||||
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <get-schema> for module "yang".
|
||||
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <get-schema> for module "ietf-inet-types".
|
||||
@@ -1636,6 +1649,59 @@ sequenceDiagram
|
||||
<vlan-id xmlns="urn:o-ran:interfaces:1.0">9</vlan-id>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<performance-measurement-objects xmlns="urn:o-ran:performance-management:1.0">
|
||||
<rx-window-measurement-interval>10</rx-window-measurement-interval>
|
||||
<tx-measurement-interval>10</tx-measurement-interval>
|
||||
<notification-interval>10</notification-interval>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_ON_TIME</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_EARLY</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_LATE</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_TOTAL</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_ON_TIME_C</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_EARLY_C</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_LATE_C</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<tx-measurement-objects>
|
||||
<measurement-object>TX_TOTAL</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</tx-measurement-objects>
|
||||
</performance-measurement-objects>
|
||||
<processing-elements xmlns="urn:o-ran:processing-element:1.0">
|
||||
<transport-session-type>ETH-INTERFACE</transport-session-type>
|
||||
<ru-elements>
|
||||
@@ -1729,8 +1795,10 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
@@ -1746,8 +1814,10 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
@@ -1763,8 +1833,10 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
@@ -1780,8 +1852,10 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
@@ -1797,9 +1871,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1807,6 +1887,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>0</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxPrachEndpoint0</name>
|
||||
@@ -1814,9 +1895,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1824,6 +1911,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>4</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxEndpoint1</name>
|
||||
@@ -1831,9 +1919,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1841,6 +1935,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>1</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxPrachEndpoint1</name>
|
||||
@@ -1848,9 +1943,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1858,6 +1959,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>5</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxEndpoint2</name>
|
||||
@@ -1865,9 +1967,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1875,6 +1983,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>2</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxPrachEndpoint2</name>
|
||||
@@ -1882,9 +1991,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1892,6 +2007,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>6</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxEndpoint3</name>
|
||||
@@ -1899,9 +2015,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1909,6 +2031,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>3</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxPrachEndpoint3</name>
|
||||
@@ -1916,9 +2039,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1926,6 +2055,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>7</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<tx-array-carriers>
|
||||
<name>TxArray0</name>
|
||||
@@ -1933,7 +2063,7 @@ sequenceDiagram
|
||||
<center-of-channel-bandwidth>3950400000</center-of-channel-bandwidth>
|
||||
<channel-bandwidth>100000000</channel-bandwidth>
|
||||
<active>ACTIVE</active>
|
||||
<gain>0.0</gain>
|
||||
<gain>24.0</gain>
|
||||
<downlink-radio-frame-offset>0</downlink-radio-frame-offset>
|
||||
<downlink-sfn-offset>0</downlink-sfn-offset>
|
||||
</tx-array-carriers>
|
||||
@@ -1957,7 +2087,7 @@ sequenceDiagram
|
||||
[HW] [MPLANE] Successfully validated candidate datastore for RU "192.168.80.9".
|
||||
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <commit> candidate datastore.
|
||||
[HW] [MPLANE] RPC reply = OK.
|
||||
[HW] [MPLANE] Successfully commited CU-planes configuration into running datastore for RU "192.168.80.9".
|
||||
[HW] [MPLANE] Successfully commited configuration into running datastore for RU "192.168.80.9".
|
||||
[HW] [MPLANE] Usage state = "idle" for RU "192.168.80.9".
|
||||
[HW] [MPLANE] Received notification from RU "192.168.80.9" at (2025-03-29T12:40:23.049085102+00:00)
|
||||
{
|
||||
@@ -2025,9 +2155,71 @@ sequenceDiagram
|
||||
"operation": "create"
|
||||
},
|
||||
...
|
||||
}
|
||||
|
||||
[HW] [MPLANE] RU "192.168.80.9" is now ready.
|
||||
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <edit-config>:
|
||||
<performance-measurement-objects xmlns="urn:o-ran:performance-management:1.0">
|
||||
<rx-window-measurement-interval>10</rx-window-measurement-interval>
|
||||
<tx-measurement-interval>10</tx-measurement-interval>
|
||||
<notification-interval>10</notification-interval>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_ON_TIME</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_EARLY</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_LATE</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_TOTAL</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_ON_TIME_C</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_EARLY_C</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_LATE_C</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<tx-measurement-objects>
|
||||
<measurement-object>TX_TOTAL</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</tx-measurement-objects>
|
||||
</performance-measurement-objects>
|
||||
|
||||
[HW] [MPLANE] RPC reply = OK.
|
||||
[HW] [MPLANE] Successfully edited the candidate datastore for RU "192.168.80.9".
|
||||
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <validate> candidate datastore.
|
||||
[HW] [MPLANE] RPC reply = OK.
|
||||
[HW] [MPLANE] Successfully validated candidate datastore for RU "192.168.80.9".
|
||||
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <commit> candidate datastore.
|
||||
[HW] [MPLANE] RPC reply = OK.
|
||||
[HW] [MPLANE] Successfully commited configuration into running datastore for RU "192.168.80.9".
|
||||
[HW] [MPLANE] Sucessfully activated PM after start-up procedure for RU "192.168.80.9".
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
+1
-1
@@ -171,7 +171,7 @@ After installing WLS, you can run the build command as shown below:
|
||||
|
||||
#### How to run OAI PNF with OAI VNF
|
||||
|
||||
Refer to the above steps in [Quickstart](.#quickstart), but run the PNF first as it is the WLS "master".
|
||||
Refer to the above steps in [Quickstart](#quickstart), but run the PNF first as it is the WLS "master".
|
||||
|
||||
#### How to run OAI PNF with OSC/Radisys O-DU
|
||||
|
||||
|
||||
@@ -174,6 +174,8 @@ static void rx_func(processingData_L1_t *info)
|
||||
int slot_rx = info->slot_rx;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
|
||||
T(T_GNB_PHY_UL_TICK, T_INT(gNB->Mod_id), T_INT(frame_rx), T_INT(slot_rx));
|
||||
|
||||
// RX processing
|
||||
int rx_slot_type = nr_slot_select(cfg, frame_rx, slot_rx);
|
||||
if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
|
||||
|
||||
+13
-4
@@ -878,11 +878,12 @@ static void fill_rf_config(RU_t *ru, char *rf_config_file)
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_request_scf_t *config, int slots_per_frame, uint16_t ofdm_symbol_size)
|
||||
static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_request_scf_t *config, const NR_DL_FRAME_PARMS *fp)
|
||||
{
|
||||
const nfapi_nr_prach_config_t *prach_config = &config->prach_config;
|
||||
const nfapi_nr_tdd_table_t *tdd_table = &config->tdd_table;
|
||||
const nfapi_nr_cell_config_t *cell_config = &config->cell_config;
|
||||
const nfapi_nr_carrier_config_t *carrier_config = &config->carrier_config;
|
||||
|
||||
DevAssert(prach_config->prach_ConfigurationIndex.tl.tag == NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG);
|
||||
split7->prach_index = prach_config->prach_ConfigurationIndex.value;
|
||||
@@ -893,7 +894,7 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_
|
||||
if (cell_config->frame_duplex_type.value == 1 /* TDD */) {
|
||||
DevAssert(tdd_table->tdd_period.tl.tag == NFAPI_NR_CONFIG_TDD_PERIOD_TAG);
|
||||
int nb_periods_per_frame = get_nb_periods_per_frame(tdd_table->tdd_period.value);
|
||||
split7->n_tdd_period = slots_per_frame / nb_periods_per_frame;
|
||||
split7->n_tdd_period = fp->slots_per_frame / nb_periods_per_frame;
|
||||
for (int slot = 0; slot < split7->n_tdd_period; ++slot) {
|
||||
for (int sym = 0; sym < 14; ++sym) {
|
||||
split7->slot_dirs[slot].sym_dir[sym] = tdd_table->max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[sym].slot_config.value;
|
||||
@@ -901,7 +902,15 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_
|
||||
}
|
||||
}
|
||||
|
||||
split7->fftSize = log2(ofdm_symbol_size);
|
||||
split7->fftSize = log2(fp->ofdm_symbol_size);
|
||||
|
||||
// M-plane related parameters
|
||||
for (size_t i = 0; i < 5 ; i++) {
|
||||
split7->dl_k0[i] = carrier_config->dl_k0[i].value;
|
||||
split7->ul_k0[i] = carrier_config->ul_k0[i].value;
|
||||
}
|
||||
split7->cp_prefix0 = fp->nb_prefix_samples0;
|
||||
split7->cp_prefix_other = fp->nb_prefix_samples;
|
||||
}
|
||||
|
||||
/* this function maps the RU tx and rx buffers to the available rf chains.
|
||||
@@ -1044,7 +1053,7 @@ void *ru_thread(void *param)
|
||||
nr_dump_frame_parms(fp);
|
||||
nr_phy_init_RU(ru);
|
||||
fill_rf_config(ru, ru->rf_config_file);
|
||||
fill_split7_2_config(&ru->openair0_cfg.split7, &ru->config, fp->slots_per_frame, fp->ofdm_symbol_size);
|
||||
fill_split7_2_config(&ru->openair0_cfg.split7, &ru->config, fp);
|
||||
|
||||
// Start IF device if any
|
||||
if (ru->nr_start_if) {
|
||||
|
||||
@@ -126,7 +126,6 @@ extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
extern int oai_exit;
|
||||
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
extern pthread_cond_t sync_cond;
|
||||
extern pthread_mutex_t sync_mutex;
|
||||
extern int sync_var;
|
||||
|
||||
+24
-25
@@ -414,7 +414,7 @@ static void UE_synch(void *arg) {
|
||||
syncData_t *syncD = (syncData_t *)arg;
|
||||
PHY_VARS_NR_UE *UE = syncD->UE;
|
||||
UE->is_synchronized = 0;
|
||||
openair0_config_t *cfg0 = &openair0_cfg[UE->rf_map.card];
|
||||
openair0_config_t *cfg0 = &UE->openair0_cfg[UE->rf_map.card];
|
||||
|
||||
if (UE->target_Nid_cell != -1) {
|
||||
LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell);
|
||||
@@ -523,7 +523,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx
|
||||
radio_tx_burst_flag_t flags = TX_BURST_INVALID;
|
||||
|
||||
if (UE->received_config_request) {
|
||||
if (openair0_cfg[0].duplex_mode == duplex_mode_FDD || get_softmodem_params()->continuous_tx) {
|
||||
if (UE->openair0_cfg[0].duplex_mode == duplex_mode_FDD || get_softmodem_params()->continuous_tx) {
|
||||
flags = TX_BURST_MIDDLE;
|
||||
// In case of Sidelink, USRP write needed only in case transmission
|
||||
// needs to be done in this slot and not based on tdd ULDL configuration.
|
||||
@@ -696,8 +696,8 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE)
|
||||
if (dl_CarrierFreq != fp->dl_CarrierFreq || ul_CarrierFreq != fp->ul_CarrierFreq) {
|
||||
fp->dl_CarrierFreq = dl_CarrierFreq;
|
||||
fp->ul_CarrierFreq = ul_CarrierFreq;
|
||||
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0);
|
||||
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &openair0_cfg[0]);
|
||||
nr_rf_card_config_freq(&UE->openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0);
|
||||
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &UE->openair0_cfg[UE->rf_map.card]);
|
||||
init_symbol_rotation(fp);
|
||||
}
|
||||
|
||||
@@ -731,12 +731,14 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
|
||||
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
|
||||
|
||||
// process what RRC thread sent to MAC
|
||||
MessageDef *msg = NULL;
|
||||
do {
|
||||
itti_poll_msg(TASK_MAC_UE, &msg);
|
||||
if (msg)
|
||||
process_msg_rcc_to_mac(msg);
|
||||
} while (msg);
|
||||
notifiedFIFO_elt_t *elt = pollNotifiedFIFO(&get_mac_inst(UE->Mod_id)->input_nf);
|
||||
if (!elt) {
|
||||
break;
|
||||
}
|
||||
process_msg_rcc_to_mac(NotifiedFifoData(elt), UE->Mod_id);
|
||||
delNotifiedFIFO_elt(elt);
|
||||
} while (true);
|
||||
|
||||
if (UE->if_inst)
|
||||
UE->if_inst->slot_indication(UE->Mod_id, false);
|
||||
@@ -966,7 +968,7 @@ void *UE_thread(void *arg)
|
||||
void *rxp[NB_ANTENNAS_RX];
|
||||
enum stream_status_e stream_status = STREAM_STATUS_UNSYNC;
|
||||
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
|
||||
int tmp = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
|
||||
int tmp = openair0_device_load(&(UE->rfdevice), &UE->openair0_cfg[0]);
|
||||
AssertFatal(tmp == 0, "Could not load the device\n");
|
||||
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
|
||||
sl_nr_phy_config_request_t *sl_cfg = NULL;
|
||||
@@ -1032,12 +1034,10 @@ void *UE_thread(void *arg)
|
||||
decoded_frame_rx = UE->SL_UE_PHY_PARAMS.sync_params.DFN;
|
||||
else {
|
||||
// We must wait the RRC layer decoded the MIB and sent us the frame number
|
||||
MessageDef *msg = NULL;
|
||||
itti_receive_msg(TASK_MAC_UE, &msg);
|
||||
if (msg)
|
||||
process_msg_rcc_to_mac(msg);
|
||||
else
|
||||
LOG_E(PHY, "It seems we arbort while trying to sync\n");
|
||||
notifiedFIFO_elt_t *elt = pullNotifiedFIFO(&mac->input_nf);
|
||||
AssertFatal(elt != NULL, "fifo error while waiting for MIB");
|
||||
process_msg_rcc_to_mac(NotifiedFifoData(elt), UE->Mod_id);
|
||||
delNotifiedFIFO_elt(elt);
|
||||
decoded_frame_rx = mac->mib_frame;
|
||||
}
|
||||
LOG_A(PHY,
|
||||
@@ -1284,20 +1284,19 @@ void *UE_thread(void *arg)
|
||||
|
||||
void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file)
|
||||
{
|
||||
NR_UE_RRC_INST_t *rrc_inst = nr_rrc_init_ue(uecap_file, nb_inst, get_nrUE_params()->nb_antennas_tx);
|
||||
NR_UE_MAC_INST_t *mac_inst = nr_l2_init_ue(nb_inst);
|
||||
AssertFatal(mac_inst, "Couldn't allocate MAC module\n");
|
||||
for (int instance_id = 0; instance_id < nb_inst; instance_id++) {
|
||||
NR_UE_RRC_INST_t* rrc = nr_rrc_init_ue(uecap_file, instance_id, get_nrUE_params()->nb_antennas_tx);
|
||||
NR_UE_MAC_INST_t *mac = nr_l2_init_ue(instance_id);
|
||||
|
||||
for (int i = 0; i < nb_inst; i++) {
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(i);
|
||||
mac->if_module = nr_ue_if_module_init(i);
|
||||
nr_rrc_set_mac_queue(instance_id, &mac->input_nf);
|
||||
mac->if_module = nr_ue_if_module_init(instance_id);
|
||||
AssertFatal(mac->if_module, "can not initialize IF module\n");
|
||||
if (!IS_SA_MODE(get_softmodem_params()) && !get_softmodem_params()->sl_mode) {
|
||||
init_nsa_message(&rrc_inst[i], reconfig_file, rbconfig_file);
|
||||
nr_rlc_activate_srb0(mac_inst[i].crnti, NULL, send_srb0_rrc);
|
||||
init_nsa_message(rrc, reconfig_file, rbconfig_file);
|
||||
nr_rlc_activate_srb0(mac->crnti, NULL, send_srb0_rrc);
|
||||
}
|
||||
//TODO: Move this call to RRC
|
||||
start_sidelink((&rrc_inst[i])->ue_id);
|
||||
start_sidelink(instance_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,8 +121,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
uint64_t sidelink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
// UE and OAI config variables
|
||||
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
int16_t node_synch_ref[MAX_NUM_CCs];
|
||||
int otg_enabled;
|
||||
double cpuf;
|
||||
@@ -249,41 +247,42 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
|
||||
|
||||
}
|
||||
|
||||
static void init_openair0()
|
||||
void init_openair0(PHY_VARS_NR_UE *ue)
|
||||
{
|
||||
int card;
|
||||
int freq_off = 0;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
bool is_sidelink = (get_softmodem_params()->sl_mode) ? true : false;
|
||||
if (is_sidelink)
|
||||
frame_parms = &PHY_vars_UE_g[0][0]->SL_UE_PHY_PARAMS.sl_frame_params;
|
||||
frame_parms = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
|
||||
|
||||
for (card=0; card<MAX_CARDS; card++) {
|
||||
openair0_config_t *cfg = &ue->openair0_cfg[card];
|
||||
uint64_t dl_carrier, ul_carrier;
|
||||
openair0_cfg[card].configFilename = NULL;
|
||||
openair0_cfg[card].sample_rate = frame_parms->samples_per_subframe * 1e3;
|
||||
openair0_cfg[card].samples_per_frame = frame_parms->samples_per_frame;
|
||||
cfg->configFilename = NULL;
|
||||
cfg->sample_rate = frame_parms->samples_per_subframe * 1e3;
|
||||
cfg->samples_per_frame = frame_parms->samples_per_frame;
|
||||
|
||||
if (frame_parms->frame_type==TDD)
|
||||
openair0_cfg[card].duplex_mode = duplex_mode_TDD;
|
||||
cfg->duplex_mode = duplex_mode_TDD;
|
||||
else
|
||||
openair0_cfg[card].duplex_mode = duplex_mode_FDD;
|
||||
cfg->duplex_mode = duplex_mode_FDD;
|
||||
|
||||
openair0_cfg[card].Mod_id = 0;
|
||||
openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL;
|
||||
openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
|
||||
openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
|
||||
openair0_cfg[card].tune_offset = get_softmodem_params()->tune_offset;
|
||||
openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx);
|
||||
openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx);
|
||||
cfg->Mod_id = 0;
|
||||
cfg->num_rb_dl = frame_parms->N_RB_DL;
|
||||
cfg->clock_source = get_softmodem_params()->clock_source;
|
||||
cfg->time_source = get_softmodem_params()->timing_source;
|
||||
cfg->tune_offset = get_softmodem_params()->tune_offset;
|
||||
cfg->tx_num_channels = min(4, frame_parms->nb_antennas_tx);
|
||||
cfg->rx_num_channels = min(4, frame_parms->nb_antennas_rx);
|
||||
|
||||
LOG_I(PHY,
|
||||
"HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
|
||||
card,
|
||||
openair0_cfg[card].sample_rate,
|
||||
openair0_cfg[card].tx_num_channels,
|
||||
openair0_cfg[card].rx_num_channels,
|
||||
duplex_mode_txt[openair0_cfg[card].duplex_mode]);
|
||||
cfg->sample_rate,
|
||||
cfg->tx_num_channels,
|
||||
cfg->rx_num_channels,
|
||||
duplex_mode_txt[cfg->duplex_mode]);
|
||||
|
||||
if (is_sidelink) {
|
||||
dl_carrier = frame_parms->dl_CarrierFreq;
|
||||
@@ -291,16 +290,18 @@ static void init_openair0()
|
||||
} 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);
|
||||
nr_rf_card_config_freq(cfg, ul_carrier, dl_carrier, freq_off);
|
||||
|
||||
nr_rf_card_config_gain(&openair0_cfg[card], rx_gain_off);
|
||||
nr_rf_card_config_gain(cfg, rx_gain_off);
|
||||
|
||||
openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
|
||||
|
||||
if (get_nrUE_params()->usrp_args) openair0_cfg[card].sdr_addrs = get_nrUE_params()->usrp_args;
|
||||
if (get_nrUE_params()->tx_subdev) openair0_cfg[card].tx_subdev = get_nrUE_params()->tx_subdev;
|
||||
if (get_nrUE_params()->rx_subdev) openair0_cfg[card].rx_subdev = get_nrUE_params()->rx_subdev;
|
||||
cfg->configFilename = get_softmodem_params()->rf_config_file;
|
||||
|
||||
if (get_nrUE_params()->usrp_args)
|
||||
cfg->sdr_addrs = get_nrUE_params()->usrp_args;
|
||||
if (get_nrUE_params()->tx_subdev)
|
||||
cfg->tx_subdev = get_nrUE_params()->tx_subdev;
|
||||
if (get_nrUE_params()->rx_subdev)
|
||||
cfg->rx_subdev = get_nrUE_params()->rx_subdev;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,9 +327,11 @@ static void trigger_stop(int sig)
|
||||
static void trigger_deregistration(int sig)
|
||||
{
|
||||
if (!stop_immediately && IS_SA_MODE(get_softmodem_params())) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DEREGISTRATION_REQ);
|
||||
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
|
||||
itti_send_msg_to_task(TASK_NAS_NRUE, 0, msg);
|
||||
for (int ue_inst = 0; ue_inst < NB_UE_INST; ue_inst++) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, ue_inst, NAS_DEREGISTRATION_REQ);
|
||||
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
|
||||
itti_send_msg_to_task(TASK_NAS_NRUE, ue_inst, msg);
|
||||
}
|
||||
stop_immediately = true;
|
||||
static const char m[] = "Press ^C again to trigger immediate shutdown\n";
|
||||
__attribute__((unused)) int unused = write(STDOUT_FILENO, m, sizeof(m) - 1);
|
||||
@@ -386,7 +389,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
//set_softmodem_sighandler();
|
||||
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
|
||||
memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS);
|
||||
memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
|
||||
// initialize logging
|
||||
logInit();
|
||||
@@ -425,12 +427,11 @@ int main(int argc, char **argv)
|
||||
char *pckg = strdup(OAI_PACKAGE_VERSION);
|
||||
LOG_I(HW, "Version: %s\n", pckg);
|
||||
|
||||
PHY_vars_UE_g = malloc(sizeof(*PHY_vars_UE_g) * NB_UE_INST);
|
||||
PHY_vars_UE_g = calloc_or_fail(NB_UE_INST, sizeof(*PHY_vars_UE_g));
|
||||
for (int inst = 0; inst < NB_UE_INST; inst++) {
|
||||
PHY_vars_UE_g[inst] = malloc(sizeof(*PHY_vars_UE_g[inst]) * MAX_NUM_CCs);
|
||||
PHY_vars_UE_g[inst] = calloc_or_fail(MAX_NUM_CCs, sizeof(*PHY_vars_UE_g[inst]));
|
||||
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
PHY_vars_UE_g[inst][CC_id] = malloc(sizeof(*PHY_vars_UE_g[inst][CC_id]));
|
||||
memset(PHY_vars_UE_g[inst][CC_id], 0, sizeof(*PHY_vars_UE_g[inst][CC_id]));
|
||||
PHY_vars_UE_g[inst][CC_id] = calloc_or_fail(1, sizeof(*PHY_vars_UE_g[inst][CC_id]));
|
||||
// All instances use the same coding interface
|
||||
PHY_vars_UE_g[inst][CC_id]->nrLDPC_coding_interface = nrLDPC_coding_interface;
|
||||
}
|
||||
@@ -498,12 +499,14 @@ int main(int argc, char **argv)
|
||||
get_softmodem_params()->numerology,
|
||||
nr_band);
|
||||
} else {
|
||||
MessageDef *msg = NULL;
|
||||
do {
|
||||
itti_poll_msg(TASK_MAC_UE, &msg);
|
||||
if (msg)
|
||||
process_msg_rcc_to_mac(msg);
|
||||
} while (msg);
|
||||
do {
|
||||
notifiedFIFO_elt_t *elt = pollNotifiedFIFO(&mac->input_nf);
|
||||
if (!elt) {
|
||||
break;
|
||||
}
|
||||
process_msg_rcc_to_mac(NotifiedFifoData(elt), inst);
|
||||
delNotifiedFIFO_elt(elt);
|
||||
} while (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);
|
||||
}
|
||||
@@ -538,10 +541,10 @@ int main(int argc, char **argv)
|
||||
get_nrUE_params()->ofdm_offset_divisor);
|
||||
sl_ue_phy_init(UE[CC_id]);
|
||||
}
|
||||
init_openair0(UE[CC_id]);
|
||||
}
|
||||
}
|
||||
|
||||
init_openair0();
|
||||
lock_memory_to_ram();
|
||||
|
||||
if (IS_SOFTMODEM_DOSCOPE) {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
|
||||
#define MAX_NUM_NR_UE_INST 32
|
||||
extern int NB_UE_INST;
|
||||
extern uint16_t ue_id_g;
|
||||
|
||||
|
||||
@@ -2308,7 +2308,7 @@ uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8
|
||||
}
|
||||
}
|
||||
#else
|
||||
const uint16_t last_idx = ((report_tlv->length + 3) / 4) - 1;
|
||||
const int16_t last_idx = ((report_tlv->length + 3) / 4) - 1;
|
||||
for (int i = 0; i < last_idx; i++) {
|
||||
if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
|
||||
return 0;
|
||||
|
||||
@@ -499,8 +499,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
pusch_pdu->scid,
|
||||
Ns,
|
||||
symbol);
|
||||
pusch_dmrs_type_t dmrs_type = pusch_pdu->dmrs_config_type == NFAPI_NR_DMRS_TYPE1 ? pusch_dmrs_type1 : pusch_dmrs_type2;
|
||||
float beta_dmrs_pusch = get_beta_dmrs_pusch(pusch_pdu->num_dmrs_cdm_grps_no_data, dmrs_type);
|
||||
float beta_dmrs_pusch = get_beta_dmrs(pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type == pusch_dmrs_type2);
|
||||
int16_t dmrs_scaling = (1 / beta_dmrs_pusch) * (1 << 14);
|
||||
nr_pusch_dmrs_rx(gNB,
|
||||
Ns,
|
||||
|
||||
@@ -117,7 +117,8 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pdsch_rb,
|
||||
uint8_t config_type)
|
||||
uint8_t config_type,
|
||||
int16_t dmrs_scaling)
|
||||
{
|
||||
typedef int array_of_w[2];
|
||||
const array_of_w *wf = (config_type == NFAPI_NR_DMRS_TYPE1) ? wf1 : wf2;
|
||||
@@ -131,6 +132,7 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||
for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) {
|
||||
int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]);
|
||||
output[i] = get_modulated(nr_gold_pdsch, i, w == 1);
|
||||
output[i] = c16mulRealShift(output[i], dmrs_scaling, 14);
|
||||
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb);
|
||||
|
||||
@@ -49,7 +49,8 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pdsch_rb,
|
||||
uint8_t config_type);
|
||||
uint8_t config_type,
|
||||
int16_t dmrs_scaling);
|
||||
|
||||
void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling);
|
||||
void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "nr_common.h"
|
||||
#include <string.h>
|
||||
#include "SCHED_NR_UE/defs.h"
|
||||
#include "nr_estimation.h"
|
||||
@@ -448,12 +449,15 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
peak_estimator(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size, &prs_toa, &ch_pwr, mean_val);
|
||||
|
||||
// adjusting the rx_gains for channel peak power
|
||||
ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(frame_params->ofdm_symbol_size);
|
||||
ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
|
||||
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
|
||||
- dB_fixed(frame_params->ofdm_symbol_size);
|
||||
|
||||
prs_meas[rxAnt]->rsrp_dBm =
|
||||
10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
||||
prs_meas[rxAnt]->rsrp_dBm = 10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
|
||||
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
|
||||
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
||||
|
||||
//prs measurements
|
||||
// prs measurements
|
||||
prs_meas[rxAnt]->gNB_id = gNB_id;
|
||||
prs_meas[rxAnt]->sfn = proc->frame_rx;
|
||||
prs_meas[rxAnt]->slot = proc->nr_slot_rx;
|
||||
@@ -1258,6 +1262,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
unsigned short scrambling_id,
|
||||
unsigned short BWPStart,
|
||||
uint8_t config_type,
|
||||
int n_dmrs_cdm_groups,
|
||||
uint16_t rb_offset,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pdsch,
|
||||
@@ -1291,8 +1296,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
|
||||
c16_t pilot[3280] __attribute__((aligned(16)));
|
||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||
float beta_dmrs_pdsch = get_beta_dmrs(n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2);
|
||||
int16_t dmrs_scaling = (int16_t)((1 / beta_dmrs_pdsch) * (1 << 14));
|
||||
const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, scrambling_id, nscid, slot, symbol);
|
||||
nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type);
|
||||
nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling);
|
||||
|
||||
delay_t delay = {0};
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
unsigned short scrambling_id,
|
||||
unsigned short BWPStart,
|
||||
uint8_t config_type,
|
||||
int n_dmrs_cdm_groups,
|
||||
uint16_t rb_offset,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pdsch,
|
||||
@@ -151,6 +152,7 @@ float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
|
||||
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
|
||||
NR_DL_FRAME_PARMS *fp,
|
||||
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
bool use_SSS);
|
||||
bool use_SSS,
|
||||
openair0_config_t *openair0_cfg);
|
||||
/** @}*/
|
||||
#endif
|
||||
|
||||
@@ -157,7 +157,9 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
||||
ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]);
|
||||
ue->measurements.wideband_cqi_tot[gNB_id] = ue->measurements.rx_power_tot_dB[gNB_id] - ue->measurements.n0_power_tot_dB;
|
||||
ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - dB_fixed(ue->measurements.n0_power_avg);
|
||||
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
||||
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB
|
||||
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
|
||||
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
||||
|
||||
LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dB (%d dBm/RE), WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
|
||||
gNB_id,
|
||||
@@ -235,7 +237,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
||||
uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier);
|
||||
float rsrp_db_per_re = 10 * log10(rsrp_avg);
|
||||
|
||||
openair0_config_t *cfg0 = &openair0_cfg[0];
|
||||
openair0_config_t *cfg0 = &ue->openair0_cfg[0];
|
||||
|
||||
ue->measurements.ssb_rsrp_dBm[ssb_index] = rsrp_db_per_re + 30 - SQ15_SQUARED_NORM_FACTOR_DB
|
||||
- ((int)cfg0->rx_gain[0] - (int)cfg0->rx_gain_offset[0])
|
||||
@@ -271,8 +273,8 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
|
||||
const uint8_t k_length = 8;
|
||||
uint8_t l_sss = (ue->symbol_offset + 2) % ue->frame_parms.symbols_per_slot;
|
||||
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
|
||||
double rx_gain = openair0_cfg[0].rx_gain[0];
|
||||
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
|
||||
double rx_gain = ue->openair0_cfg[0].rx_gain[0];
|
||||
double rx_gain_offset = ue->openair0_cfg[0].rx_gain_offset[0];
|
||||
|
||||
ue->measurements.n0_power_tot = 0;
|
||||
|
||||
@@ -344,7 +346,8 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
|
||||
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
|
||||
NR_DL_FRAME_PARMS *fp,
|
||||
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
bool use_SSS)
|
||||
bool use_SSS,
|
||||
openair0_config_t *openair0_cfg)
|
||||
{
|
||||
SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch;
|
||||
uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
|
||||
|
||||
@@ -238,7 +238,7 @@ static int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
|
||||
|
||||
*rsrp = rsrp_sum/meas_count;
|
||||
*rsrp_dBm = dB_fixed(*rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
|
||||
- ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
||||
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
LOG_I(NR_PHY, "RSRP = %i (%i dBm)\n", *rsrp, *rsrp_dBm);
|
||||
|
||||
@@ -80,7 +80,7 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
|
||||
/* compute the MMSE up to 4x4 matrices */
|
||||
static void nr_dlsch_mmse(uint32_t rx_size_symbol,
|
||||
unsigned char n_rx,
|
||||
unsigned char n_tx, // number of layer
|
||||
unsigned char nl, // number of layer
|
||||
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
|
||||
c16_t dl_ch_mag[][n_rx][rx_size_symbol],
|
||||
c16_t dl_ch_magb[][n_rx][rx_size_symbol],
|
||||
@@ -203,7 +203,7 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
|
||||
uint32_t len,
|
||||
unsigned short nb_rb);
|
||||
static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol,
|
||||
short n_tx,
|
||||
short nl,
|
||||
short n_rx,
|
||||
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
|
||||
int ***rho,
|
||||
@@ -1456,7 +1456,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
|
||||
int length,
|
||||
uint32_t noise_var)
|
||||
{
|
||||
uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0);
|
||||
uint32_t nb_rb_0 = (length + 11) / 12;
|
||||
c16_t determ_fin[12 * nb_rb_0] __attribute__((aligned(32)));
|
||||
|
||||
///Allocate H^*H matrix elements and sub elements
|
||||
@@ -1513,7 +1513,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
|
||||
determ_fin, // determin
|
||||
nb_rb_0,
|
||||
fp_flag, // fixed point flag
|
||||
shift - (fp_flag == 1 ? 2 : 0)); // the out put is Q15
|
||||
shift - (fp_flag == 1 ? 1 : 0)); // the out put is Q15
|
||||
|
||||
// multiply Matrix inversion pf H_h_H by the rx signal vector
|
||||
c16_t outtemp[12 * nb_rb_0] __attribute__((aligned(32)));
|
||||
@@ -1531,7 +1531,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
|
||||
(c16_t *)(rxdataF_comp[ctx][0] + symbol * rx_size_symbol),
|
||||
outtemp,
|
||||
sizeofArray(outtemp),
|
||||
shift - (fp_flag == 1 ? 2 : 0));
|
||||
shift - (fp_flag == 1 ? 1 : 0));
|
||||
nr_a_sum_b(rxdataF_zforcing[rtx], outtemp, nb_rb_0); // a = a + b
|
||||
}
|
||||
#ifdef DEBUG_DLSCH_DEMOD
|
||||
@@ -1582,13 +1582,9 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
|
||||
dl_ch_mag128b_0[0] = mmtmpD2;
|
||||
dl_ch_mag128r_0[0] = mmtmpD2;
|
||||
|
||||
dl_ch_mag128_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128);
|
||||
dl_ch_mag128_0[0] = simde_mm_slli_epi16(dl_ch_mag128_0[0],1);
|
||||
|
||||
dl_ch_mag128b_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
|
||||
dl_ch_mag128b_0[0] = simde_mm_slli_epi16(dl_ch_mag128b_0[0],1);
|
||||
dl_ch_mag128r_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
|
||||
dl_ch_mag128r_0[0] = simde_mm_slli_epi16(dl_ch_mag128r_0[0],1);
|
||||
dl_ch_mag128_0[0] = simde_mm_mulhrs_epi16(dl_ch_mag128_0[0], QAM_amp128);
|
||||
dl_ch_mag128b_0[0] = simde_mm_mulhrs_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
|
||||
dl_ch_mag128r_0[0] = simde_mm_mulhrs_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
|
||||
|
||||
determ_fin_128 += 1;
|
||||
dl_ch_mag128_0 += 1;
|
||||
|
||||
@@ -518,7 +518,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
|
||||
sync_params->DFN,
|
||||
sync_params->slot_offset);
|
||||
|
||||
UE->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false);
|
||||
UE->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false, UE->openair0_cfg);
|
||||
|
||||
UE->init_sync_frame = sync_params->remaining_frames;
|
||||
result.rx_offset = sync_params->rx_offset;
|
||||
|
||||
@@ -91,8 +91,8 @@ The function pointers are set once before calling the mapping funcion for
|
||||
all symbols based on different parameters. Then the mapping is done for
|
||||
each symbol by calling the function pointers.
|
||||
*/
|
||||
static void (*map_dmrs_ptr)(const unsigned int, const c16_t *, c16_t *);
|
||||
static void (*map_data_dmrs_ptr)(const unsigned int num_cdm_no_data, const c16_t *, c16_t *);
|
||||
typedef void (*map_dmrs_func_t)(const unsigned int, const c16_t *, c16_t *);
|
||||
typedef void (*map_data_dmrs_func_t)(const unsigned int, const c16_t *, c16_t *);
|
||||
|
||||
/*
|
||||
The following set of functions map dmrs and/or data REs in one RB based on
|
||||
@@ -191,7 +191,9 @@ static void map_over_dc(const unsigned int right_dc,
|
||||
const c16_t **ptrs,
|
||||
const c16_t **dmrs,
|
||||
const c16_t **data,
|
||||
c16_t **out)
|
||||
c16_t **out,
|
||||
map_dmrs_func_t map_data_dmrs_ptr,
|
||||
map_dmrs_func_t map_dmrs_ptr)
|
||||
{
|
||||
// if first RE is DC no need to map in this function
|
||||
if (right_dc == 0)
|
||||
@@ -277,7 +279,9 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
|
||||
const c16_t *dmrs_seq,
|
||||
const c16_t *ptrs_seq,
|
||||
const c16_t **data,
|
||||
c16_t *out)
|
||||
c16_t *out,
|
||||
map_dmrs_func_t map_dmrs_ptr,
|
||||
map_data_dmrs_func_t map_data_dmrs_ptr)
|
||||
{
|
||||
const unsigned int abs_start_rb = p.bwp_start + p.start_rb;
|
||||
const unsigned int start_sc = (p.first_sc_offset + abs_start_rb * NR_NB_SC_PER_RB) % p.fft_size;
|
||||
@@ -297,7 +301,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
|
||||
// map RB at DC
|
||||
if (rb_over_dc) {
|
||||
// if DC is in middle of RB, the following function handles it.
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, NULL, &out_tmp);
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, NULL, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
|
||||
continue;
|
||||
} else {
|
||||
// else just move the pointer and following function will map the rb
|
||||
@@ -315,7 +319,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
|
||||
for (unsigned int rb = 0; rb < p.nb_rb; rb++) {
|
||||
if (rb == dc_rb) {
|
||||
if (rb_over_dc) {
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, &data_tmp, &out_tmp);
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
|
||||
continue;
|
||||
} else {
|
||||
out_tmp -= p.fft_size;
|
||||
@@ -339,7 +343,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
|
||||
if (rb < non_ptrs_rb || ptrs_idx_rb % p.K_ptrs) {
|
||||
if (rb == dc_rb) {
|
||||
if (rb_over_dc) {
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp);
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
|
||||
continue;
|
||||
} else {
|
||||
out_tmp -= p.fft_size;
|
||||
@@ -351,7 +355,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
|
||||
} else {
|
||||
if (rb == dc_rb) {
|
||||
if (rb_over_dc) {
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, ptrs_idx_re, &p_mod_ptrs, NULL, &data_tmp, &out_tmp);
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, ptrs_idx_re, &p_mod_ptrs, NULL, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
|
||||
continue;
|
||||
} else {
|
||||
out_tmp -= p.fft_size;
|
||||
@@ -370,7 +374,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
|
||||
for (unsigned int rb = 0; rb < p.nb_rb; rb++) {
|
||||
if (rb == dc_rb) {
|
||||
if (rb_over_dc) {
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp);
|
||||
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
|
||||
continue;
|
||||
} else {
|
||||
out_tmp -= p.fft_size;
|
||||
@@ -396,7 +400,7 @@ static void dmrs_amp_mult(const uint32_t dmrs_port,
|
||||
const pusch_dmrs_type_t dmrs_type,
|
||||
const unsigned int num_cdm_groups_no_data)
|
||||
{
|
||||
float beta_dmrs_pusch = get_beta_dmrs_pusch(num_cdm_groups_no_data, dmrs_type);
|
||||
float beta_dmrs_pusch = get_beta_dmrs(num_cdm_groups_no_data, dmrs_type == pusch_dmrs_type2);
|
||||
/* short array that hold amplitude for k_prime = 0 and k_prime = 1 */
|
||||
int32_t alpha_dmrs[2] __attribute((aligned(16)));
|
||||
for (int_fast8_t i = 0; i < sizeofArray(alpha_dmrs); i++) {
|
||||
@@ -420,6 +424,8 @@ static void map_symbols(const nr_phy_pxsch_params_t p,
|
||||
c16_t *out)
|
||||
{
|
||||
// asign the function pointers
|
||||
map_dmrs_func_t map_dmrs_ptr = NULL;
|
||||
map_data_dmrs_func_t map_data_dmrs_ptr = NULL;
|
||||
if (p.dmrs_type == pusch_dmrs_type1) {
|
||||
map_dmrs_ptr = map_dmrs_type1_cdm1_rb;
|
||||
map_data_dmrs_ptr = (p.num_cdm_no_data == 1) ? map_data_dmrs_type1_cdm1_rb : NULL;
|
||||
@@ -460,7 +466,9 @@ static void map_symbols(const nr_phy_pxsch_params_t p,
|
||||
mod_dmrs_amp,
|
||||
mod_ptrs_amp,
|
||||
&cur_data, // increments every symbol
|
||||
out + l * p.fft_size);
|
||||
out + l * p.fft_size,
|
||||
map_dmrs_ptr,
|
||||
map_data_dmrs_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -336,6 +336,7 @@ typedef struct {
|
||||
|
||||
/// Top-level PHY Data Structure for UE
|
||||
typedef struct PHY_VARS_NR_UE_s {
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
/// \brief Module ID indicator for this instance
|
||||
uint8_t Mod_id;
|
||||
/// \brief Component carrier ID for this PHY instance
|
||||
|
||||
@@ -553,6 +553,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
dlschCfg->dlDmrsScramblingId,
|
||||
dlschCfg->BWPStart,
|
||||
dlschCfg->dmrsConfigType,
|
||||
dlschCfg->n_dmrs_cdm_groups,
|
||||
dlschCfg->rb_offset,
|
||||
ue->frame_parms.first_carrier_offset + (dlschCfg->BWPStart + dlschCfg->start_rb) * 12,
|
||||
dlschCfg->number_rbs,
|
||||
|
||||
@@ -227,7 +227,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
|
||||
sym = (sym == 0) ? 5 : sym + 1;
|
||||
}
|
||||
|
||||
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false);
|
||||
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false, ue->openair0_cfg);
|
||||
|
||||
LOG_D(NR_PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
|
||||
|
||||
|
||||
@@ -924,8 +924,7 @@ printf("%d\n", slot);
|
||||
|
||||
init_nr_ue_transport(UE);
|
||||
|
||||
nr_l2_init_ue(1);
|
||||
UE_mac = get_mac_inst(0);
|
||||
UE_mac = nr_l2_init_ue(0);
|
||||
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
|
||||
|
||||
UE->if_inst = nr_ue_if_module_init(0);
|
||||
|
||||
@@ -780,8 +780,7 @@ int main(int argc, char *argv[])
|
||||
init_nr_ue_transport(UE);
|
||||
|
||||
//Configure UE
|
||||
nr_l2_init_ue(1);
|
||||
NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0);
|
||||
NR_UE_MAC_INST_t* UE_mac = nr_l2_init_ue(0);
|
||||
|
||||
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
|
||||
|
||||
|
||||
@@ -85,14 +85,6 @@ MESSAGE_DEF(NAS_INIT_NOS1_IF, MESSAGE_PRIORITY_MED, nas_nos1_msg_t, nas_init_nos
|
||||
MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process)
|
||||
MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFrameProcess, nr_rrc_frame_process)
|
||||
|
||||
// UE: RRC -> MAC messages
|
||||
MESSAGE_DEF(NR_MAC_RRC_CONFIG_RESET, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_reset_t, nr_mac_rrc_config_reset)
|
||||
MESSAGE_DEF(NR_MAC_RRC_CONFIG_CG, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_cg_t, nr_mac_rrc_config_cg)
|
||||
MESSAGE_DEF(NR_MAC_RRC_RESUME_RB, MESSAGE_PRIORITY_MED, nr_mac_rrc_resume_rb_t, nr_mac_rrc_resume_rb)
|
||||
MESSAGE_DEF(NR_MAC_RRC_CONFIG_MIB, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_mib_t, nr_mac_rrc_config_mib)
|
||||
MESSAGE_DEF(NR_MAC_RRC_CONFIG_SIB1, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_sib1_t, nr_mac_rrc_config_sib1)
|
||||
MESSAGE_DEF(NR_MAC_RRC_CONFIG_OTHER_SIB, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_other_sib_t, nr_mac_rrc_config_other_sib)
|
||||
|
||||
// eNB: RLC -> RRC messages
|
||||
MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication)
|
||||
MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, nas_pdu_session_req_t, nas_pdu_session_req)
|
||||
|
||||
@@ -105,12 +105,6 @@
|
||||
|
||||
#define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa
|
||||
#define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req
|
||||
#define NR_MAC_RRC_CONFIG_RESET(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_reset
|
||||
#define NR_MAC_RRC_CONFIG_CG(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_cg
|
||||
#define NR_MAC_RRC_RESUME_RB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_resume_rb
|
||||
#define NR_MAC_RRC_CONFIG_MIB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_mib
|
||||
#define NR_MAC_RRC_CONFIG_SIB1(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_sib1
|
||||
#define NR_MAC_RRC_CONFIG_OTHER_SIB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_other_sib
|
||||
|
||||
#define NR_RRC_RLC_MAXRTX(mSGpTR) (mSGpTR)->ittiMsg.nr_rlc_maxrtx_indication
|
||||
|
||||
@@ -497,4 +491,25 @@ typedef struct {
|
||||
bool can_start_ra;
|
||||
} nr_mac_rrc_config_other_sib_t;
|
||||
|
||||
enum payload_type {
|
||||
NR_MAC_RRC_CONFIG_RESET,
|
||||
NR_MAC_RRC_CONFIG_CG,
|
||||
NR_MAC_RRC_CONFIG_MIB,
|
||||
NR_MAC_RRC_CONFIG_SIB1,
|
||||
NR_MAC_RRC_CONFIG_OTHER_SIB,
|
||||
NR_MAC_RRC_RESUME_RB
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum payload_type payload_type;
|
||||
union {
|
||||
nr_mac_rrc_config_reset_t config_reset;
|
||||
nr_mac_rrc_config_cg_t config_cg;
|
||||
nr_mac_rrc_config_mib_t config_mib;
|
||||
nr_mac_rrc_config_sib1_t config_sib1;
|
||||
nr_mac_rrc_config_other_sib_t config_other_sib;
|
||||
nr_mac_rrc_resume_rb_t resume_rb;
|
||||
} payload;
|
||||
} nr_mac_rrc_message_t;
|
||||
|
||||
#endif /* RRC_MESSAGES_TYPES_H_ */
|
||||
|
||||
@@ -654,6 +654,7 @@ typedef struct NR_UE_MAC_INST_s {
|
||||
bool msg3_C_RNTI;
|
||||
pthread_mutex_t if_mutex;
|
||||
ue_mac_stats_t stats;
|
||||
notifiedFIFO_t input_nf;
|
||||
} NR_UE_MAC_INST_t;
|
||||
|
||||
static inline int GET_NTN_UE_K_OFFSET(const ntn_timing_advance_componets_t *ntn_ta, int scs)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "RRC/NR_UE/rrc_proto.h"
|
||||
#include <pthread.h>
|
||||
static NR_UE_MAC_INST_t *nr_ue_mac_inst;
|
||||
static NR_UE_MAC_INST_t *nr_ue_mac_inst[MAX_NUM_NR_UE_INST] = {0};
|
||||
|
||||
void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data)
|
||||
{
|
||||
@@ -70,6 +70,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
||||
mac->p_Max_alt = INT_MIN;
|
||||
mac->msg3_C_RNTI = false;
|
||||
mac->ntn_ta.ntn_params_changed = false;
|
||||
initNotifiedFIFO(&mac->input_nf);
|
||||
reset_mac_inst(mac);
|
||||
|
||||
// need to inizialize because might not been setup (optional timer)
|
||||
@@ -124,37 +125,38 @@ NR_UE_L2_STATE_t nr_ue_get_sync_state(module_id_t mod_id)
|
||||
return mac->state;
|
||||
}
|
||||
|
||||
NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst)
|
||||
NR_UE_MAC_INST_t *nr_l2_init_ue(int instance_id)
|
||||
{
|
||||
//init mac here
|
||||
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(nb_inst, sizeof(NR_UE_MAC_INST_t));
|
||||
AssertFatal(nr_ue_mac_inst, "Couldn't allocate %d instances of MAC module\n", nb_inst);
|
||||
AssertFatal(instance_id < MAX_NUM_NR_UE_INST, "instance_id %d is out of range\n", instance_id);
|
||||
AssertFatal(nr_ue_mac_inst[instance_id] == NULL, "MAC instance %d already initialized\n", instance_id);
|
||||
nr_ue_mac_inst[instance_id] = calloc_or_fail(1, sizeof(NR_UE_MAC_INST_t));
|
||||
|
||||
for (int j = 0; j < nb_inst; j++) {
|
||||
NR_UE_MAC_INST_t *mac = &nr_ue_mac_inst[j];
|
||||
mac->ue_id = j;
|
||||
nr_ue_init_mac(mac);
|
||||
int ret = pthread_mutex_init(&mac->if_mutex, NULL);
|
||||
AssertFatal(ret == 0, "Mutex init failed\n");
|
||||
nr_ue_mac_default_configs(mac);
|
||||
if (IS_SA_MODE(get_softmodem_params()))
|
||||
ue_init_config_request(mac, get_slots_per_frame_from_scs(get_softmodem_params()->numerology));
|
||||
NR_UE_MAC_INST_t *mac = nr_ue_mac_inst[instance_id];
|
||||
mac->ue_id = instance_id;
|
||||
nr_ue_init_mac(mac);
|
||||
int ret = pthread_mutex_init(&mac->if_mutex, NULL);
|
||||
AssertFatal(ret == 0, "Mutex init failed\n");
|
||||
nr_ue_mac_default_configs(mac);
|
||||
if (IS_SA_MODE(get_softmodem_params()))
|
||||
ue_init_config_request(mac, get_slots_per_frame_from_scs(get_softmodem_params()->numerology));
|
||||
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
int rc = nr_rlc_module_init(NR_RLC_OP_MODE_UE);
|
||||
AssertFatal(rc == 0, "Could not initialize RLC layer\n");
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
int rc = nr_rlc_module_init(NR_RLC_OP_MODE_UE);
|
||||
AssertFatal(rc == 0, "Could not initialize RLC layer\n");
|
||||
nr_rlc_activate_srb0(instance_id, NULL, send_srb0_rrc);
|
||||
|
||||
for (int j = 0; j < nb_inst; j++) {
|
||||
nr_rlc_activate_srb0(j, NULL, send_srb0_rrc);
|
||||
}
|
||||
|
||||
return (nr_ue_mac_inst);
|
||||
return nr_ue_mac_inst[instance_id];
|
||||
}
|
||||
|
||||
NR_UE_MAC_INST_t *get_mac_inst(module_id_t module_id)
|
||||
{
|
||||
NR_UE_MAC_INST_t *mac = &nr_ue_mac_inst[(int)module_id];
|
||||
AssertFatal(mac, "Couldn't get MAC inst %d\n", module_id);
|
||||
AssertFatal(module_id < MAX_NUM_NR_UE_INST, "module_id %d is out of range\n", module_id);
|
||||
NR_UE_MAC_INST_t *mac = nr_ue_mac_inst[module_id];
|
||||
if (mac == NULL) return NULL;
|
||||
AssertFatal(mac->ue_id == module_id, "MAC ID %d doesn't match with input %d\n", mac->ue_id, module_id);
|
||||
return mac;
|
||||
}
|
||||
|
||||
@@ -755,8 +755,13 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
|
||||
dlsch_pdu->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2;
|
||||
} else {
|
||||
dlsch_pdu->SubcarrierSpacing = current_DL_BWP->scs;
|
||||
if (nr_timer_is_active(&mac->ra.response_window_timer) && rnti_type == TYPE_RA_RNTI_) {
|
||||
dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
|
||||
if (rnti_type == TYPE_RA_RNTI_) {
|
||||
if (nr_timer_is_active(&mac->ra.response_window_timer)) {
|
||||
dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
|
||||
} else {
|
||||
// Discard the DCI
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
|
||||
}
|
||||
|
||||
@@ -1314,6 +1314,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
if (len == 0)
|
||||
break;
|
||||
|
||||
T(T_GNB_MAC_LCID_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(lcid), T_INT(len * 8), T_INT(nr_rlc_tx_list_occupancy(rnti, lcid)));
|
||||
header->R = 0;
|
||||
header->F = 1;
|
||||
header->LCID = lcid;
|
||||
@@ -1387,6 +1388,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
|
||||
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock.buf, TBS));
|
||||
T(T_GNB_MAC_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(sched_pdsch->mcs), T_INT(TBS));
|
||||
}
|
||||
|
||||
const int ntx_req = TX_req->Number_of_PDUs;
|
||||
|
||||
@@ -485,6 +485,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
UE->mac_stats.ul.total_sdu_bytes += mac_len;
|
||||
UE->mac_stats.ul.lc_bytes[lcid] += mac_len;
|
||||
}
|
||||
T(T_GNB_MAC_LCID_UL, T_INT(UE->rnti), T_INT(frameP), T_INT(slot), T_INT(lcid), T_INT(mac_len * 8));
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_DTCH ...(UL_SCH_LCID_DTCH + 28):
|
||||
@@ -512,6 +513,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
else
|
||||
sched_ctrl->estimated_ul_buffer = 0;
|
||||
}
|
||||
T(T_GNB_MAC_LCID_UL, T_INT(UE->rnti), T_INT(frameP), T_INT(slot), T_INT(lcid), T_INT(mac_len * 8));
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
|
||||
@@ -1498,8 +1500,17 @@ void handle_nr_srs_measurements(const module_id_t module_id,
|
||||
nfapi_nr_srs_indication_pdu_t *srs_ind)
|
||||
{
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||
LOG_D(NR_MAC, "(%d.%d) Received SRS indication for UE %04x\n", frame, slot, srs_ind->rnti);
|
||||
if (srs_ind->report_type == 0) {
|
||||
//SCF 222.10.04 Table 3-129 Report type = 0 means a null report, we can skip unpacking it
|
||||
return;
|
||||
}
|
||||
|
||||
if (srs_ind->timing_advance_offset == 0xFFFF) {
|
||||
LOG_W(NR_MAC, "Invalid timing advance offset for RNTI %04x\n", srs_ind->rnti);
|
||||
return;
|
||||
}
|
||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||
|
||||
#ifdef SRS_IND_DEBUG
|
||||
LOG_I(NR_MAC, "frame = %i\n", frame);
|
||||
@@ -1518,12 +1529,6 @@ void handle_nr_srs_measurements(const module_id_t module_id,
|
||||
return;
|
||||
}
|
||||
|
||||
if (srs_ind->timing_advance_offset == 0xFFFF) {
|
||||
LOG_W(NR_MAC, "Invalid timing advance offset for RNTI %04x\n", srs_ind->rnti);
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
NR_mac_stats_t *stats = &UE->mac_stats;
|
||||
nfapi_srs_report_tlv_t *report_tlv = &srs_ind->report_tlv;
|
||||
@@ -2467,6 +2472,8 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE
|
||||
sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes,
|
||||
sched_ctrl->tpc0);
|
||||
|
||||
T(T_GNB_MAC_UL, T_INT(UE->rnti), T_INT(frame), T_INT(slot), T_INT(sched_pusch->mcs), T_INT(sched_pusch->tb_size));
|
||||
|
||||
/* PUSCH in a later slot, but corresponding DCI now! */
|
||||
const int index = ul_buffer_index(sched_pusch->frame,
|
||||
sched_pusch->slot,
|
||||
|
||||
@@ -125,6 +125,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
|
||||
ret->common.reestablishment = nr_rlc_entity_am_reestablishment;
|
||||
ret->common.delete_entity = nr_rlc_entity_am_delete;
|
||||
ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space;
|
||||
ret->common.tx_list_occupancy = nr_rlc_entity_am_tx_list_occupancy;
|
||||
ret->common.get_stats = nr_rlc_entity_get_stats;
|
||||
|
||||
ret->common.deliver_sdu = deliver_sdu;
|
||||
@@ -186,6 +187,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_um(
|
||||
ret->common.reestablishment = nr_rlc_entity_um_reestablishment;
|
||||
ret->common.delete_entity = nr_rlc_entity_um_delete;
|
||||
ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space;
|
||||
ret->common.tx_list_occupancy = nr_rlc_entity_um_tx_list_occupancy;
|
||||
ret->common.get_stats = nr_rlc_entity_get_stats;
|
||||
|
||||
ret->common.deliver_sdu = deliver_sdu;
|
||||
@@ -226,6 +228,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm(
|
||||
ret->common.reestablishment = nr_rlc_entity_tm_reestablishment;
|
||||
ret->common.delete_entity = nr_rlc_entity_tm_delete;
|
||||
ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space;
|
||||
ret->common.tx_list_occupancy = nr_rlc_entity_tm_tx_list_occupancy;
|
||||
ret->common.get_stats = nr_rlc_entity_get_stats;
|
||||
|
||||
ret->common.deliver_sdu = deliver_sdu;
|
||||
|
||||
@@ -116,6 +116,7 @@ typedef struct nr_rlc_entity_t {
|
||||
void (*delete_entity)(struct nr_rlc_entity_t *entity);
|
||||
|
||||
int (*available_tx_space)(struct nr_rlc_entity_t *entity);
|
||||
int (*tx_list_occupancy)(struct nr_rlc_entity_t *entity);
|
||||
|
||||
void (*get_stats)(struct nr_rlc_entity_t *entity, nr_rlc_statistics_t *out);
|
||||
|
||||
|
||||
@@ -2116,3 +2116,8 @@ int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *_entity)
|
||||
return entity->tx_maxsize - entity->tx_size;
|
||||
}
|
||||
|
||||
int nr_rlc_entity_am_tx_list_occupancy(nr_rlc_entity_t *_entity)
|
||||
{
|
||||
nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity;
|
||||
return entity->tx_size;
|
||||
}
|
||||
|
||||
@@ -101,5 +101,6 @@ void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
|
||||
void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity);
|
||||
void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity);
|
||||
int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *entity);
|
||||
int nr_rlc_entity_am_tx_list_occupancy(nr_rlc_entity_t *_entity);
|
||||
|
||||
#endif /* _NR_RLC_ENTITY_AM_H_ */
|
||||
|
||||
@@ -221,3 +221,9 @@ int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *_entity)
|
||||
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
|
||||
return entity->tx_maxsize - entity->tx_size;
|
||||
}
|
||||
|
||||
int nr_rlc_entity_tm_tx_list_occupancy(nr_rlc_entity_t *_entity)
|
||||
{
|
||||
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
|
||||
return entity->tx_size;
|
||||
}
|
||||
|
||||
@@ -56,5 +56,6 @@ void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
|
||||
void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity);
|
||||
void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity);
|
||||
int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *entity);
|
||||
int nr_rlc_entity_tm_tx_list_occupancy(nr_rlc_entity_t *_entity);
|
||||
|
||||
#endif /* _NR_RLC_ENTITY_TM_H_ */
|
||||
|
||||
@@ -765,3 +765,9 @@ int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *_entity)
|
||||
nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity;
|
||||
return entity->tx_maxsize - entity->tx_size;
|
||||
}
|
||||
|
||||
int nr_rlc_entity_um_tx_list_occupancy(nr_rlc_entity_t *_entity)
|
||||
{
|
||||
nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity;
|
||||
return entity->tx_size;
|
||||
}
|
||||
|
||||
@@ -80,5 +80,6 @@ void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
|
||||
void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity);
|
||||
void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity);
|
||||
int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *entity);
|
||||
int nr_rlc_entity_um_tx_list_occupancy(nr_rlc_entity_t *_entity);
|
||||
|
||||
#endif /* _NR_RLC_ENTITY_UM_H_ */
|
||||
|
||||
@@ -320,6 +320,25 @@ int nr_rlc_get_available_tx_space(const int ue_id, const logical_chan_id_t chann
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nr_rlc_tx_list_occupancy(int ue_id, logical_chan_id_t lcid)
|
||||
{
|
||||
int ret;
|
||||
|
||||
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
||||
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lcid);
|
||||
|
||||
if (rb != NULL) {
|
||||
ret = rb->tx_list_occupancy(rb);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nr_rlc_module_init(nr_rlc_op_mode_t mode)
|
||||
{
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
@@ -80,6 +80,8 @@ void nr_rlc_reconfigure_entity(int ue_id, int lc_id, NR_RLC_Config_t *rlc_Config
|
||||
|
||||
int nr_rlc_get_available_tx_space(const int ue_id, const logical_chan_id_t channel_idP);
|
||||
|
||||
int nr_rlc_tx_list_occupancy(int ue_id, logical_chan_id_t lcid);
|
||||
|
||||
void nr_rlc_activate_avg_time_to_tx(const int ue_id, const logical_chan_id_t channel_id, const bool is_on);
|
||||
|
||||
void nr_rlc_srb_recv_sdu(const int ue_id, const logical_chan_id_t channel_id, unsigned char *buf, int size);
|
||||
|
||||
@@ -1312,7 +1312,7 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio
|
||||
// resume RAR response window timer if MSG2 decoding failed
|
||||
nr_timer_suspension(&mac->ra.response_window_timer);
|
||||
} else {
|
||||
LOG_I(PHY, "RAR-Msg2 decoded\n");
|
||||
LOG_I(PHY, "[UE %d] RAR-Msg2 decoded\n", mac->ue_id);
|
||||
}
|
||||
ret_mask |= (handle_dlsch(mac, dl_info, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
|
||||
break;
|
||||
|
||||
@@ -121,42 +121,40 @@ void nr_mac_rrc_data_ind_ue(const module_id_t module_id,
|
||||
}
|
||||
}
|
||||
|
||||
void process_msg_rcc_to_mac(MessageDef *msg)
|
||||
void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id)
|
||||
{
|
||||
instance_t ue_id = ITTI_MSG_DESTINATION_INSTANCE(msg);
|
||||
switch (ITTI_MSG_ID(msg)) {
|
||||
switch (msg->payload_type) {
|
||||
case NR_MAC_RRC_CONFIG_RESET:
|
||||
nr_rrc_mac_config_req_reset(ue_id, NR_MAC_RRC_CONFIG_RESET(msg).cause);
|
||||
nr_rrc_mac_config_req_reset(instance_id, msg->payload.config_reset.cause);
|
||||
break;
|
||||
case NR_MAC_RRC_CONFIG_CG:
|
||||
nr_rrc_mac_config_req_cg(ue_id, 0, NR_MAC_RRC_CONFIG_CG(msg).cellGroupConfig, NR_MAC_RRC_CONFIG_CG(msg).UE_NR_Capability);
|
||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, NR_MAC_RRC_CONFIG_CG(msg).cellGroupConfig);
|
||||
nr_rrc_mac_config_req_cg(instance_id, 0, msg->payload.config_cg.cellGroupConfig, msg->payload.config_cg.UE_NR_Capability);
|
||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, msg->payload.config_cg.cellGroupConfig);
|
||||
break;
|
||||
case NR_MAC_RRC_CONFIG_MIB:
|
||||
nr_rrc_mac_config_req_mib(ue_id,
|
||||
nr_rrc_mac_config_req_mib(instance_id,
|
||||
0,
|
||||
NR_MAC_RRC_CONFIG_MIB(msg).bcch->message.choice.mib,
|
||||
NR_MAC_RRC_CONFIG_MIB(msg).get_sib,
|
||||
NR_MAC_RRC_CONFIG_MIB(msg).access_barred);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, NR_MAC_RRC_CONFIG_MIB(msg).bcch);
|
||||
msg->payload.config_mib.bcch->message.choice.mib,
|
||||
msg->payload.config_mib.get_sib,
|
||||
msg->payload.config_mib.access_barred);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, msg->payload.config_mib.bcch);
|
||||
break;
|
||||
case NR_MAC_RRC_CONFIG_SIB1: {
|
||||
NR_SIB1_t *sib1 = NR_MAC_RRC_CONFIG_SIB1(msg).sib1;
|
||||
bool can_start_ra = NR_MAC_RRC_CONFIG_SIB1(msg).can_start_ra;
|
||||
nr_rrc_mac_config_req_sib1(ue_id, 0, sib1, can_start_ra);
|
||||
SEQUENCE_free(&asn_DEF_NR_SIB1, NR_MAC_RRC_CONFIG_SIB1(msg).sib1, ASFM_FREE_EVERYTHING);
|
||||
NR_SIB1_t *sib1 = msg->payload.config_sib1.sib1;
|
||||
bool can_start_ra = msg->payload.config_sib1.can_start_ra;
|
||||
nr_rrc_mac_config_req_sib1(instance_id, 0, sib1, can_start_ra);
|
||||
SEQUENCE_free(&asn_DEF_NR_SIB1, msg->payload.config_sib1.sib1, ASFM_FREE_EVERYTHING);
|
||||
} break;
|
||||
case NR_MAC_RRC_CONFIG_OTHER_SIB: {
|
||||
bool can_start_ra = NR_MAC_RRC_CONFIG_OTHER_SIB(msg).can_start_ra;
|
||||
nr_rrc_mac_config_other_sib(ue_id, NR_MAC_RRC_CONFIG_OTHER_SIB(msg).sib19, can_start_ra);
|
||||
bool can_start_ra = msg->payload.config_other_sib.can_start_ra;
|
||||
nr_rrc_mac_config_other_sib(instance_id, msg->payload.config_other_sib.sib19, can_start_ra);
|
||||
} break;
|
||||
case NR_MAC_RRC_RESUME_RB:
|
||||
nr_rrc_mac_resume_rb(ue_id, NR_MAC_RRC_RESUME_RB(msg).is_srb, NR_MAC_RRC_RESUME_RB(msg).rb_id);
|
||||
nr_rrc_mac_resume_rb(instance_id, msg->payload.resume_rb.is_srb, msg->payload.resume_rb.rb_id);
|
||||
break;
|
||||
default:
|
||||
LOG_E(NR_MAC, "Unexpected msg from RRC: %d\n", ITTI_MSG_ID(msg));
|
||||
LOG_E(NR_MAC, "Unexpected msg from RRC: %d\n", msg->payload_type);
|
||||
}
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
|
||||
}
|
||||
|
||||
void nr_mac_rrc_inactivity_timer_ind(const module_id_t mod_id)
|
||||
|
||||
@@ -42,6 +42,6 @@ void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti, bool prepare_
|
||||
void nr_ue_rrc_timer_trigger(int instance, int frame, int gnb_id);
|
||||
void nr_mac_rrc_ra_ind(const module_id_t mod_id, bool success);
|
||||
void nsa_sendmsg_to_lte_ue(const void *message, size_t msg_len, Rrc_Msg_Type_t msg_type);
|
||||
void process_msg_rcc_to_mac(MessageDef *msg);
|
||||
void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id);
|
||||
#endif
|
||||
|
||||
|
||||
+163
-124
@@ -72,7 +72,7 @@
|
||||
#include "nr_nas_msg.h"
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
|
||||
|
||||
static NR_UE_RRC_INST_t *NR_UE_rrc_inst;
|
||||
static NR_UE_RRC_INST_t *NR_UE_rrc_inst[MAX_NUM_NR_UE_INST] = {0};
|
||||
/* NAS Attach request with IMSI */
|
||||
static const char nr_nas_attach_req_imsi_dummy_NSA_case[] = {
|
||||
0x07,
|
||||
@@ -149,9 +149,29 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
||||
|
||||
static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers);
|
||||
|
||||
NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance)
|
||||
/**
|
||||
* @brief Sends an RRC message to the connected UE MAC instance.
|
||||
*
|
||||
* @param rrc UE RRC instance structure
|
||||
* @param msg RRC message to be sent to MAC
|
||||
*/
|
||||
static void nr_rrc_send_msg_to_mac(NR_UE_RRC_INST_t *rrc, nr_mac_rrc_message_t *msg)
|
||||
{
|
||||
return &NR_UE_rrc_inst[instance];
|
||||
AssertFatal(rrc->mac_input_nf != NULL, "MAC input NF is NULL for UE %ld\n", rrc->ue_id);
|
||||
notifiedFIFO_elt_t *nf_msg = newNotifiedFIFO_elt(sizeof(nr_mac_rrc_message_t), 0, NULL, NULL);
|
||||
nr_mac_rrc_message_t *rrc_msg = NotifiedFifoData(nf_msg);
|
||||
memcpy(rrc_msg, msg, sizeof(nr_mac_rrc_message_t));
|
||||
pushNotifiedFIFO(rrc->mac_input_nf, nf_msg);
|
||||
}
|
||||
|
||||
NR_UE_RRC_INST_t *get_NR_UE_rrc_inst(int instance)
|
||||
{
|
||||
AssertFatal(instance >= 0 && instance < MAX_NUM_NR_UE_INST, "RRC instance %d out of bounds\n", instance);
|
||||
NR_UE_RRC_INST_t *rrc = NR_UE_rrc_inst[instance];
|
||||
if (rrc == NULL)
|
||||
return NULL;
|
||||
AssertFatal(rrc->ue_id == instance, "RRC ID %d doesn't match with input %d\n", (int)rrc->ue_id, instance);
|
||||
return rrc;
|
||||
}
|
||||
|
||||
static NR_RB_status_t get_DRB_status(const NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id)
|
||||
@@ -281,7 +301,6 @@ static void nr_rrc_process_ntnconfig(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *S
|
||||
|
||||
static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, NR_UE_RRC_INST_t *rrc, int frame)
|
||||
{
|
||||
instance_t ue_id = rrc->ue_id;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN);
|
||||
|
||||
// Dump contents
|
||||
@@ -365,10 +384,12 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si,
|
||||
}
|
||||
|
||||
if (sib19) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_OTHER_SIB);
|
||||
asn_copy(&asn_DEF_NR_SIB19_r17, (void **)&NR_MAC_RRC_CONFIG_OTHER_SIB(msg).sib19, sib19);
|
||||
NR_MAC_RRC_CONFIG_OTHER_SIB(msg).can_start_ra = rrc->is_NTN_UE;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_OTHER_SIB;
|
||||
nr_mac_rrc_config_other_sib_t *sib19_msg = &rrc_msg.payload.config_other_sib;
|
||||
asn_copy(&asn_DEF_NR_SIB19_r17, (void **)&sib19_msg->sib19, sib19);
|
||||
sib19_msg->can_start_ra = rrc->is_NTN_UE;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT);
|
||||
}
|
||||
@@ -502,10 +523,13 @@ static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_inf
|
||||
nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1);
|
||||
// RRC storage of SIB1 timers and constants (eg needed in re-establishment)
|
||||
UPDATE_IE(rrc->timers_and_constants.sib1_TimersAndConstants, sib1->ue_TimersAndConstants, NR_UE_TimersAndConstants_t);
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_SIB1);
|
||||
NR_MAC_RRC_CONFIG_SIB1(msg).sib1 = sib1;
|
||||
NR_MAC_RRC_CONFIG_SIB1(msg).can_start_ra = !rrc->is_NTN_UE;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_SIB1;
|
||||
nr_mac_rrc_config_sib1_t *config_sib1 = &rrc_msg.payload.config_sib1;
|
||||
config_sib1->sib1 = sib1;
|
||||
config_sib1->can_start_ra = !rrc->is_NTN_UE;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
}
|
||||
|
||||
static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCReconfiguration_v1530_IEs_t *rec_1530, int gNB_index)
|
||||
@@ -644,12 +668,12 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_
|
||||
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index);
|
||||
|
||||
AssertFatal(!IS_SA_MODE(get_softmodem_params()), "secondaryCellGroup only used in NSA for now\n");
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_CG);
|
||||
// cellGroupConfig will be managed by MAC
|
||||
NR_MAC_RRC_CONFIG_CG(msg).cellGroupConfig = cellGroupConfig;
|
||||
// UE_NR_Capability remain a race condition between this rrc thread and mac thread
|
||||
NR_MAC_RRC_CONFIG_CG(msg).UE_NR_Capability = rrc->UECap.UE_NR_Capability;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_CG;
|
||||
nr_mac_rrc_config_cg_t *config_cg = &rrc_msg.payload.config_cg;
|
||||
config_cg->cellGroupConfig = cellGroupConfig;
|
||||
config_cg->UE_NR_Capability = rrc->UECap.UE_NR_Capability;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
}
|
||||
if (ie->measConfig) {
|
||||
LOG_I(NR_RRC, "RRCReconfiguration includes Measurement Configuration\n");
|
||||
@@ -731,67 +755,63 @@ static bool verify_ue_cap(NR_UE_NR_Capability_t *UE_NR_Capability, int nb_antenn
|
||||
return true;
|
||||
}
|
||||
|
||||
NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx)
|
||||
NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int instance_id, int num_ant_tx)
|
||||
{
|
||||
NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(nb_inst, sizeof(NR_UE_RRC_INST_t));
|
||||
AssertFatal(NR_UE_rrc_inst, "Couldn't allocate %d instances of RRC module\n", nb_inst);
|
||||
AssertFatal(instance_id < MAX_NUM_NR_UE_INST, "RRC instance %d out of bounds\n", instance_id);
|
||||
AssertFatal(NR_UE_rrc_inst[instance_id] == NULL, "RRC instance %d already initialized\n", instance_id);
|
||||
NR_UE_rrc_inst[instance_id] = calloc_or_fail(1, sizeof(NR_UE_RRC_INST_t));
|
||||
NR_UE_RRC_INST_t *rrc = NR_UE_rrc_inst[instance_id];
|
||||
rrc->ue_id = instance_id;
|
||||
// fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
|
||||
rrc->selected_plmn_identity = 1;
|
||||
rrc->ra_trigger = RA_NOT_RUNNING;
|
||||
rrc->dl_bwp_id = 0;
|
||||
rrc->ul_bwp_id = 0;
|
||||
rrc->as_security_activated = false;
|
||||
rrc->detach_after_release = false;
|
||||
rrc->reconfig_after_reestab = false;
|
||||
/* 5G-S-TMSI */
|
||||
rrc->fiveG_S_TMSI = UINT64_MAX;
|
||||
rrc->access_barred = false;
|
||||
|
||||
for(int nr_ue = 0; nr_ue < nb_inst; nr_ue++) {
|
||||
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[nr_ue];
|
||||
rrc->ue_id = nr_ue;
|
||||
// fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
|
||||
rrc->selected_plmn_identity = 1;
|
||||
rrc->ra_trigger = RA_NOT_RUNNING;
|
||||
rrc->dl_bwp_id = 0;
|
||||
rrc->ul_bwp_id = 0;
|
||||
rrc->as_security_activated = false;
|
||||
rrc->detach_after_release = false;
|
||||
rrc->reconfig_after_reestab = false;
|
||||
/* 5G-S-TMSI */
|
||||
rrc->fiveG_S_TMSI = UINT64_MAX;
|
||||
rrc->access_barred = false;
|
||||
|
||||
FILE *f = NULL;
|
||||
if (uecap_file)
|
||||
f = fopen(uecap_file, "r");
|
||||
if (f) {
|
||||
char UE_NR_Capability_xer[65536];
|
||||
size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
|
||||
if (size == 0 || size == sizeof UE_NR_Capability_xer) {
|
||||
LOG_E(NR_RRC, "UE Capabilities XER file %s is too large (%ld)\n", uecap_file, size);
|
||||
}
|
||||
else {
|
||||
asn_dec_rval_t dec_rval =
|
||||
xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&rrc->UECap.UE_NR_Capability, UE_NR_Capability_xer, size);
|
||||
assert(dec_rval.code == RC_OK);
|
||||
}
|
||||
fclose(f);
|
||||
/* Verify consistency of num PHY antennas vs UE Capabilities */
|
||||
verify_ue_cap(rrc->UECap.UE_NR_Capability, num_ant_tx);
|
||||
FILE *f = NULL;
|
||||
if (uecap_file)
|
||||
f = fopen(uecap_file, "r");
|
||||
if (f) {
|
||||
char UE_NR_Capability_xer[65536];
|
||||
size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
|
||||
if (size == 0 || size == sizeof UE_NR_Capability_xer) {
|
||||
LOG_E(NR_RRC, "UE Capabilities XER file %s is too large (%ld)\n", uecap_file, size);
|
||||
} else {
|
||||
asn_dec_rval_t dec_rval =
|
||||
xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&rrc->UECap.UE_NR_Capability, UE_NR_Capability_xer, size);
|
||||
assert(dec_rval.code == RC_OK);
|
||||
}
|
||||
|
||||
memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants));
|
||||
set_default_timers_and_constants(&rrc->timers_and_constants);
|
||||
|
||||
for (int j = 0; j < NR_NUM_SRB; j++)
|
||||
rrc->Srb[j] = RB_NOT_PRESENT;
|
||||
for (int j = 1; j <= MAX_DRBS_PER_UE; j++)
|
||||
set_DRB_status(rrc, j, RB_NOT_PRESENT);
|
||||
// SRB0 activated by default
|
||||
rrc->Srb[0] = RB_ESTABLISHED;
|
||||
for (int j = 0; j < NR_MAX_NUM_LCID; j++)
|
||||
rrc->active_RLC_entity[j] = false;
|
||||
|
||||
for (int i = 0; i < NB_CNX_UE; i++) {
|
||||
rrcPerNB_t *ptr = &rrc->perNB[i];
|
||||
ptr->SInfo = (NR_UE_RRC_SI_INFO){0};
|
||||
init_SI_timers(&ptr->SInfo);
|
||||
}
|
||||
|
||||
init_sidelink(rrc);
|
||||
fclose(f);
|
||||
/* Verify consistency of num PHY antennas vs UE Capabilities */
|
||||
verify_ue_cap(rrc->UECap.UE_NR_Capability, num_ant_tx);
|
||||
}
|
||||
|
||||
return NR_UE_rrc_inst;
|
||||
memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants));
|
||||
set_default_timers_and_constants(&rrc->timers_and_constants);
|
||||
|
||||
for (int j = 0; j < NR_NUM_SRB; j++)
|
||||
rrc->Srb[j] = RB_NOT_PRESENT;
|
||||
for (int j = 1; j <= MAX_DRBS_PER_UE; j++)
|
||||
set_DRB_status(rrc, j, RB_NOT_PRESENT);
|
||||
// SRB0 activated by default
|
||||
rrc->Srb[0] = RB_ESTABLISHED;
|
||||
for (int j = 0; j < NR_MAX_NUM_LCID; j++)
|
||||
rrc->active_RLC_entity[j] = false;
|
||||
|
||||
for (int i = 0; i < NB_CNX_UE; i++) {
|
||||
rrcPerNB_t *ptr = &rrc->perNB[i];
|
||||
ptr->SInfo = (NR_UE_RRC_SI_INFO){0};
|
||||
init_SI_timers(&ptr->SInfo);
|
||||
}
|
||||
|
||||
init_sidelink(rrc);
|
||||
return rrc;
|
||||
}
|
||||
|
||||
bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type)
|
||||
@@ -973,12 +993,13 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc,
|
||||
SI_info->sib_pending = true;
|
||||
}
|
||||
if (bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_MIB);
|
||||
// mac will manage the pointer
|
||||
NR_MAC_RRC_CONFIG_MIB(msg).bcch = bcch_message;
|
||||
NR_MAC_RRC_CONFIG_MIB(msg).get_sib = get_sib;
|
||||
NR_MAC_RRC_CONFIG_MIB(msg).access_barred = barred;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_MIB;
|
||||
nr_mac_rrc_config_mib_t *config_mib = &rrc_msg.payload.config_mib;
|
||||
config_mib->bcch = bcch_message;
|
||||
config_mib->get_sib = get_sib;
|
||||
config_mib->access_barred = barred;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
} else {
|
||||
LOG_E(NR_RRC, "RRC-received BCCH message is not a MIB\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message);
|
||||
@@ -1036,10 +1057,11 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti)
|
||||
nr_rlc_reconfigure_entity(rrc->ue_id, lc_id, NULL);
|
||||
// resume SRB1
|
||||
rrc->Srb[srb_id] = RB_ESTABLISHED;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB);
|
||||
NR_MAC_RRC_RESUME_RB(msg).is_srb = true;
|
||||
NR_MAC_RRC_RESUME_RB(msg).rb_id = 1;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_RESUME_RB;
|
||||
rrc_msg.payload.resume_rb.is_srb = true;
|
||||
rrc_msg.payload.resume_rb.rb_id = 1;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
break;
|
||||
case DURING_HANDOVER:
|
||||
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
|
||||
@@ -1260,10 +1282,12 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
||||
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index);
|
||||
|
||||
LOG_D(RRC, "Sending CellGroupConfig to MAC the pointer will be managed by mac\n");
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_CG);
|
||||
NR_MAC_RRC_CONFIG_CG(msg).cellGroupConfig = cellGroupConfig;
|
||||
NR_MAC_RRC_CONFIG_CG(msg).UE_NR_Capability = rrc->UECap.UE_NR_Capability;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_CG;
|
||||
nr_mac_rrc_config_cg_t *mac_msg = &rrc_msg.payload.config_cg;
|
||||
mac_msg->cellGroupConfig = cellGroupConfig;
|
||||
mac_msg->UE_NR_Capability = rrc->UECap.UE_NR_Capability;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
}
|
||||
|
||||
static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const uint8_t Transaction_id)
|
||||
@@ -1345,9 +1369,10 @@ static void nr_rrc_rrcsetup_fallback(NR_UE_RRC_INST_t *rrc)
|
||||
// default MAC Cell Group configuration and CCCH configuration
|
||||
// TODO to be completed
|
||||
NR_UE_MAC_reset_cause_t cause = RRC_SETUP_REESTAB_RESUME;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
|
||||
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
|
||||
rrc_msg.payload.config_reset.cause = cause;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
|
||||
// indicate to upper layers fallback of the RRC connection
|
||||
// TODO
|
||||
@@ -1411,9 +1436,10 @@ static void nr_rrc_process_rrcreject(NR_UE_RRC_INST_t *rrc, const NR_RRCReject_t
|
||||
|
||||
// reset MAC and release the default MAC Cell Group configuration
|
||||
NR_UE_MAC_reset_cause_t cause = REJECT;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
|
||||
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
|
||||
rrc_msg.payload.config_reset.cause = cause;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
|
||||
// if waitTime is configured in the RRCReject: start timer T302, with the timer value set to the waitTime
|
||||
NR_RejectWaitTime_t *waitTime = NULL;
|
||||
@@ -2121,18 +2147,20 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
|
||||
// resume SRB2 and DRBs that are suspended
|
||||
if (rrc->Srb[2] == RB_SUSPENDED) {
|
||||
rrc->Srb[2] = RB_ESTABLISHED;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB);
|
||||
NR_MAC_RRC_RESUME_RB(msg).is_srb = true;
|
||||
NR_MAC_RRC_RESUME_RB(msg).rb_id = 2;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_RESUME_RB;
|
||||
rrc_msg.payload.resume_rb.is_srb = true;
|
||||
rrc_msg.payload.resume_rb.rb_id = 2;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
}
|
||||
for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
|
||||
if (get_DRB_status(rrc, i) == RB_SUSPENDED) {
|
||||
set_DRB_status(rrc, i, RB_ESTABLISHED);
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB);
|
||||
NR_MAC_RRC_RESUME_RB(msg).is_srb = false;
|
||||
NR_MAC_RRC_RESUME_RB(msg).rb_id = i;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_RESUME_RB;
|
||||
rrc_msg.payload.resume_rb.is_srb = true;
|
||||
rrc_msg.payload.resume_rb.rb_id = i;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
}
|
||||
}
|
||||
rrc->reconfig_after_reestab = false;
|
||||
@@ -2246,7 +2274,7 @@ void *rrc_nrue(void *notUsed)
|
||||
instance_t instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p);
|
||||
LOG_D(NR_RRC, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p));
|
||||
|
||||
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance];
|
||||
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(instance);
|
||||
AssertFatal(instance == rrc->ue_id, "Instance %ld received from ITTI doesn't matach with UE-ID %ld\n", instance, rrc->ue_id);
|
||||
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
@@ -2335,11 +2363,11 @@ void *rrc_nrue(void *notUsed)
|
||||
|
||||
case NR_RRC_DCCH_DATA_IND:
|
||||
nr_rrc_ue_decode_dcch(rrc,
|
||||
NR_RRC_DCCH_DATA_IND(msg_p).dcch_index,
|
||||
NR_RRC_DCCH_DATA_IND(msg_p).sdu_p,
|
||||
NR_RRC_DCCH_DATA_IND(msg_p).sdu_size,
|
||||
NR_RRC_DCCH_DATA_IND(msg_p).gNB_index,
|
||||
&NR_RRC_DCCH_DATA_IND(msg_p).msg_integrity);
|
||||
NR_RRC_DCCH_DATA_IND(msg_p).dcch_index,
|
||||
NR_RRC_DCCH_DATA_IND(msg_p).sdu_p,
|
||||
NR_RRC_DCCH_DATA_IND(msg_p).sdu_size,
|
||||
NR_RRC_DCCH_DATA_IND(msg_p).gNB_index,
|
||||
&NR_RRC_DCCH_DATA_IND(msg_p).msg_integrity);
|
||||
/* this is allocated by itti_malloc in PDCP task (deliver_sdu_srb)
|
||||
then passed to the RRC task and freed after use */
|
||||
free(NR_RRC_DCCH_DATA_IND(msg_p).sdu_p);
|
||||
@@ -2511,9 +2539,10 @@ static void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, NR_Reestab
|
||||
// reset MAC
|
||||
// release spCellConfig, if configured
|
||||
// perform cell selection in accordance with the cell selection process
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
|
||||
NR_MAC_RRC_CONFIG_RESET(msg).cause = RE_ESTABLISHMENT;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
|
||||
rrc_msg.payload.config_reset.cause = RE_ESTABLISHMENT;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
}
|
||||
|
||||
static void nr_rrc_ue_generate_rrcReestablishmentComplete(const NR_UE_RRC_INST_t *rrc,
|
||||
@@ -2541,7 +2570,7 @@ void *recv_msgs_from_lte_ue(void *args_p)
|
||||
LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen);
|
||||
continue;
|
||||
}
|
||||
process_lte_nsa_msg(NR_UE_rrc_inst, &msg, recvLen);
|
||||
process_lte_nsa_msg(get_NR_UE_rrc_inst(0), &msg, recvLen);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -2679,8 +2708,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
|
||||
|
||||
uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer);
|
||||
uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size;
|
||||
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, nr_SecondaryCellGroup_size);
|
||||
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size);
|
||||
process_nsa_message(get_NR_UE_rrc_inst(0), nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, nr_SecondaryCellGroup_size);
|
||||
process_nsa_message(get_NR_UE_rrc_inst(0), nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size);
|
||||
LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id);
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE];
|
||||
size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id);
|
||||
@@ -2886,9 +2915,10 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
|
||||
|
||||
// reset MAC
|
||||
NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
|
||||
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
|
||||
rrc_msg.payload.config_reset.cause = cause;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
|
||||
// enter RRC_IDLE
|
||||
LOG_I(NR_RRC, "RRC moved into IDLE state\n");
|
||||
@@ -2917,9 +2947,11 @@ void handle_t300_expiry(NR_UE_RRC_INST_t *rrc)
|
||||
|
||||
// reset MAC, release the MAC configuration
|
||||
NR_UE_MAC_reset_cause_t cause = T300_EXPIRY;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
|
||||
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
|
||||
rrc_msg.payload.config_reset.cause = cause;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
|
||||
// TODO handle connEstFailureControl
|
||||
// TODO inform upper layers about the failure to establish the RRC connection
|
||||
}
|
||||
@@ -2935,16 +2967,17 @@ void handle_t430_expiry(NR_UE_RRC_INST_t *rrc)
|
||||
}
|
||||
// Indicate MAC that UL SYNC is LOST
|
||||
NR_UE_MAC_reset_cause_t cause = UL_SYNC_LOST_T430_EXPIRED;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
|
||||
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
|
||||
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
|
||||
rrc_msg.payload.config_reset.cause = cause;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
}
|
||||
|
||||
//This calls the sidelink preconf message after RRC, MAC instances are created.
|
||||
void start_sidelink(int instance)
|
||||
{
|
||||
|
||||
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance];
|
||||
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(instance);
|
||||
|
||||
if (get_softmodem_params()->sl_mode == 2) {
|
||||
|
||||
@@ -2953,3 +2986,9 @@ void start_sidelink(int instance)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void nr_rrc_set_mac_queue(instance_t instance, notifiedFIFO_t *mac_input_nf)
|
||||
{
|
||||
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(instance);
|
||||
rrc->mac_input_nf = mac_input_nf;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "RRC/NR/nr_rrc_common.h"
|
||||
#include "as_message.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "notified_fifo.h"
|
||||
|
||||
#define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE
|
||||
#define MAX_MEAS_OBJ 64
|
||||
@@ -248,6 +249,7 @@ typedef struct NR_UE_RRC_INST_s {
|
||||
NR_SL_PreconfigurationNR_r16_t *sl_preconfig;
|
||||
// NTN params
|
||||
bool is_NTN_UE;
|
||||
notifiedFIFO_t *mac_input_nf;
|
||||
} NR_UE_RRC_INST_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -106,6 +106,8 @@ void nr_rrc_ue_decode_NR_SBCCH_SL_BCH_Message(NR_UE_RRC_INST_t *rrc,
|
||||
const sdu_size_t pdu_len,
|
||||
const uint16_t rx_slss_id);
|
||||
|
||||
void nr_rrc_set_mac_queue(instance_t instance, notifiedFIFO_t *mac_input_nf);
|
||||
|
||||
/** @}*/
|
||||
#endif
|
||||
|
||||
|
||||
@@ -76,9 +76,7 @@
|
||||
#include "key_nas_deriver.h"
|
||||
#include "nr-uesoftmodem.h"
|
||||
|
||||
#define MAX_NAS_UE 4
|
||||
|
||||
static nr_ue_nas_t nr_ue_nas[MAX_NAS_UE] = {0};
|
||||
static nr_ue_nas_t nr_ue_nas[MAX_NUM_NR_UE_INST] = {0};
|
||||
|
||||
#define FOREACH_STATE(TYPE_DEF) \
|
||||
TYPE_DEF(NAS_SECURITY_NO_SECURITY_CONTEXT, 0) \
|
||||
@@ -676,7 +674,7 @@ static void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas)
|
||||
|
||||
nr_ue_nas_t *get_ue_nas_info(module_id_t module_id)
|
||||
{
|
||||
DevAssert(module_id < MAX_NAS_UE);
|
||||
AssertFatal(module_id < MAX_NUM_NR_UE_INST, "Invalid module_id %d\n", module_id);
|
||||
if (!nr_ue_nas[module_id].uicc) {
|
||||
nr_ue_nas[module_id].uicc = checkUicc(module_id);
|
||||
nr_ue_nas[module_id].UE_id = module_id;
|
||||
|
||||
@@ -198,6 +198,13 @@ typedef struct split7_config {
|
||||
} slot_dirs[160];
|
||||
/*! this is the exponent in 2^X for the FFT size */
|
||||
uint16_t fftSize;
|
||||
|
||||
// M-plane related parameters
|
||||
uint16_t dl_k0[5];
|
||||
uint16_t ul_k0[5];
|
||||
uint16_t cp_prefix0;
|
||||
uint16_t cp_prefix_other;
|
||||
|
||||
} split7_config_t;
|
||||
|
||||
/*! \brief RF frontend parameters set by application */
|
||||
|
||||
@@ -21,14 +21,12 @@
|
||||
|
||||
#include "config-mplane.h"
|
||||
#include "rpc-send-recv.h"
|
||||
#include "yang/get-yang.h"
|
||||
#include "yang/create-yang-config.h"
|
||||
#include "common/utils/assertions.h"
|
||||
|
||||
#include <libyang/libyang.h>
|
||||
#include <nc_client.h>
|
||||
|
||||
bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const openair0_config_t *oai, const size_t num_rus)
|
||||
static bool edit_config_mplane(ru_session_t *ru_session, const char *content)
|
||||
{
|
||||
int timeout = CLI_RPC_REPLY_TIMEOUT;
|
||||
struct nc_rpc *rpc;
|
||||
@@ -39,37 +37,21 @@ bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const open
|
||||
NC_RPC_EDIT_TESTOPT test = NC_RPC_EDIT_TESTOPT_UNKNOWN;
|
||||
NC_RPC_EDIT_ERROPT err = NC_RPC_EDIT_ERROPT_UNKNOWN;
|
||||
|
||||
bool success = false;
|
||||
|
||||
struct ly_ctx *ctx = NULL;
|
||||
success = load_yang_models(ru_session, buffer, &ctx);
|
||||
AssertError(success, return false, "[MPLANE] Unable to continue.\n");
|
||||
|
||||
char *content = NULL;
|
||||
success = configure_ru_from_yang(&ctx, ru_session, oai, num_rus, &content);
|
||||
AssertError(success, return false, "[MPLANE] Unable to create content for <edit-config> RPC.\n");
|
||||
|
||||
MP_LOG_I("RPC request to RU \"%s\" = <edit-config>:\n%s\n", ru_session->ru_ip_add, content);
|
||||
rpc = nc_rpc_edit(target, op, test, err, content, param);
|
||||
AssertError(rpc != NULL, return false, "[MPLANE] <edit-config> RPC creation failed.\n");
|
||||
|
||||
success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL);
|
||||
bool success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL);
|
||||
AssertError(success, return false, "[MPLANE] Failed to edit configuration for the candidate datastore.\n");
|
||||
|
||||
MP_LOG_I("Successfully edited the candidate datastore for RU \"%s\".\n", ru_session->ru_ip_add);
|
||||
|
||||
nc_rpc_free(rpc);
|
||||
free(content);
|
||||
#ifdef MPLANE_V1
|
||||
ly_ctx_destroy(ctx, NULL);
|
||||
#elif defined MPLANE_V2
|
||||
ly_ctx_destroy(ctx);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validate_config_mplane(ru_session_t *ru_session)
|
||||
static bool validate_config_mplane(ru_session_t *ru_session)
|
||||
{
|
||||
int timeout = CLI_RPC_REPLY_TIMEOUT;
|
||||
struct nc_rpc *rpc;
|
||||
@@ -92,7 +74,7 @@ bool validate_config_mplane(ru_session_t *ru_session)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool commit_config_mplane(ru_session_t *ru_session)
|
||||
static bool commit_config_mplane(ru_session_t *ru_session)
|
||||
{
|
||||
int timeout = CLI_RPC_REPLY_TIMEOUT;
|
||||
struct nc_rpc *rpc;
|
||||
@@ -109,9 +91,25 @@ bool commit_config_mplane(ru_session_t *ru_session)
|
||||
bool success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL);
|
||||
AssertError(success, return false, "[MPLANE] Failed to commit candidate datastore.\n");
|
||||
|
||||
MP_LOG_I("Successfully commited CU-planes configuration into running datastore for RU \"%s\".\n", ru_session->ru_ip_add);
|
||||
MP_LOG_I("Successfully commited configuration into running datastore for RU \"%s\".\n", ru_session->ru_ip_add);
|
||||
|
||||
nc_rpc_free(rpc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool edit_val_commmit_rpc(ru_session_t *ru_session, const char *content)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
success = edit_config_mplane(ru_session, content);
|
||||
AssertError(success, return false, "[MPLANE] Unable to edit the RU configuration.\n");
|
||||
|
||||
success = validate_config_mplane(ru_session);
|
||||
AssertError(success, return false, "[MPLANE] Unable to validate the RU configuration.\n");
|
||||
|
||||
success = commit_config_mplane(ru_session);
|
||||
AssertError(success, return false, "[MPLANE] Unable to commit the RU configuration.\n");
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
#include "ru-mplane-api.h"
|
||||
#include "radio/COMMON/common_lib.h"
|
||||
|
||||
bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const openair0_config_t *oai, const size_t num_rus);
|
||||
|
||||
bool validate_config_mplane(ru_session_t *ru_session);
|
||||
|
||||
bool commit_config_mplane(ru_session_t *ru_session);
|
||||
bool edit_val_commmit_rpc(ru_session_t *ru_session, const char *content);
|
||||
|
||||
#endif /* CONFIGURE_MPLANE_H */
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "connect-mplane.h"
|
||||
#include "init-mplane.h"
|
||||
#include "common/utils/assertions.h"
|
||||
|
||||
#include <libyang/libyang.h>
|
||||
@@ -37,9 +38,8 @@ static int my_auth_hostkey_check(const char *hostname, ssh_session session, void
|
||||
bool connect_mplane(ru_session_t *ru_session)
|
||||
{
|
||||
int port = NC_PORT_SSH;
|
||||
char *user = "oranbenetel";
|
||||
|
||||
nc_client_ssh_set_username(user);
|
||||
nc_client_ssh_set_username(ru_session->username);
|
||||
|
||||
nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 1); // ssh-key identification
|
||||
nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1);
|
||||
@@ -47,11 +47,11 @@ bool connect_mplane(ru_session_t *ru_session)
|
||||
|
||||
nc_client_ssh_set_auth_hostkey_check_clb(my_auth_hostkey_check, "DATA"); // host-key identification
|
||||
|
||||
MP_LOG_I("RPC request to RU \"%s\" = <connect> with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, user, port);
|
||||
MP_LOG_I("RPC request to RU \"%s\" = <connect> with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, ru_session->username, port);
|
||||
ru_session->session = nc_connect_ssh(ru_session->ru_ip_add, port, NULL);
|
||||
AssertError(ru_session->session != NULL, return false, "[MPLANE] RU IP address %s unreachable. Maybe M-plane is disabled on the RU?\n", ru_session->ru_ip_add);
|
||||
|
||||
MP_LOG_I("Successfuly connected to RU \"%s\" with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, user, port);
|
||||
MP_LOG_I("Successfuly connected to RU \"%s\" with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, ru_session->username, port);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -64,9 +64,18 @@ void disconnect_mplane(void *rus_disconnect)
|
||||
ru_session_t *ru_session = &ru_session_list->ru_session[i];
|
||||
if (ru_session->session == NULL)
|
||||
continue;
|
||||
MP_LOG_I("Sending PM de-activation request for RU \"%s\".\n", ru_session->ru_ip_add);
|
||||
bool success = pm_conf(ru_session, "false");
|
||||
if (success)
|
||||
MP_LOG_I("Successfully de-activated PM for RU \"%s\".\n", ru_session->ru_ip_add);
|
||||
MP_LOG_I("Disconnecting from RU \"%s\".\n", ru_session->ru_ip_add);
|
||||
nc_session_free(ru_session->session, NULL);
|
||||
ru_session->session = NULL;
|
||||
#ifdef MPLANE_V1
|
||||
ly_ctx_destroy((struct ly_ctx *)ru_session->ctx, NULL);
|
||||
#elif defined MPLANE_V2
|
||||
ly_ctx_destroy((struct ly_ctx *)ru_session->ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
nc_client_destroy();
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "subscribe-mplane.h"
|
||||
#include "config-mplane.h"
|
||||
#include "xml/get-xml.h"
|
||||
#include "yang/get-yang.h"
|
||||
#include "yang/create-yang-config.h"
|
||||
|
||||
#include <libyang/libyang.h>
|
||||
#include <nc_client.h>
|
||||
@@ -94,11 +96,14 @@ bool init_mplane(ru_session_list_t *ru_session_list)
|
||||
|
||||
char **ru_ip_addrs = gpd(fhip, nump, ORAN_CONFIG_RU_IP_ADDR)->strlistptr;
|
||||
int num_rus = gpd(fhip, nump, ORAN_CONFIG_RU_IP_ADDR)->numelt;
|
||||
char **ru_usernames = gpd(fhip, nump, ORAN_CONFIG_RU_USERNAME)->strlistptr;
|
||||
int num_ru_users = gpd(fhip, nump, ORAN_CONFIG_RU_USERNAME)->numelt;
|
||||
char **du_mac_addr = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->strlistptr;
|
||||
int num_dus = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->numelt;
|
||||
int32_t *vlan_tag = gpd(fhip, nump, ORAN_CONFIG_VLAN_TAG)->iptr;
|
||||
int num_vlan_tags = gpd(fhip, nump, ORAN_CONFIG_VLAN_TAG)->numelt;
|
||||
|
||||
AssertError(num_rus == num_ru_users, return false, "[MPLANE] Number of RUs should be equal to the number of users, one for each.\n");
|
||||
AssertError(num_dus == num_vlan_tags, return false, "[MPLANE] Number of DU MAC addresses should be equal to the number of VLAN tags.\n");
|
||||
|
||||
int num_cu_planes = num_dus / num_rus;
|
||||
@@ -110,6 +115,8 @@ bool init_mplane(ru_session_list_t *ru_session_list)
|
||||
ru_session->session = NULL;
|
||||
ru_session->ru_ip_add = calloc(strlen(ru_ip_addrs[i]) + 1, sizeof(char));
|
||||
memcpy(ru_session->ru_ip_add, ru_ip_addrs[i], strlen(ru_ip_addrs[i]) + 1);
|
||||
ru_session->username = calloc(strlen(ru_usernames[i]) + 1, sizeof(char));
|
||||
memcpy(ru_session->username, ru_usernames[i], strlen(ru_usernames[i]) + 1);
|
||||
|
||||
// store DU MAC addresses and VLAN tags
|
||||
ru_session->ru_mplane_config.num_cu_planes = num_cu_planes;
|
||||
@@ -175,15 +182,21 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz
|
||||
success = get_uplane_info(operational_ds, &ru_session->ru_mplane_config);
|
||||
AssertError(success, return false, "[MPLANE] Unable to get U-plane info from RU operational datastore.\n");
|
||||
|
||||
// Performance Management
|
||||
success = get_pm_object_list(operational_ds, &ru_session->pm_stats);
|
||||
AssertError(success, return false, "[MPLANE] Unable to retrieve performance measurement names from RU \"%s\".\n", ru_session->ru_ip_add);
|
||||
|
||||
success = load_yang_models(ru_session, operational_ds);
|
||||
AssertError(success, return false, "[MPLANE] Unable to load yang models.\n");
|
||||
|
||||
if (ru_session->ru_notif.ptp_state) {
|
||||
success = edit_config_mplane(ru_session, operational_ds, oai, num_rus);
|
||||
AssertError(success, return false, "[MPLANE] Unable to edit the RU configuration.\n");
|
||||
char *content = NULL;
|
||||
success = configure_ru_from_yang(ru_session, oai, num_rus, &content);
|
||||
AssertError(success, return false, "[MPLANE] Unable to create content for <edit-config> RPC for start-up procedure.\n");
|
||||
|
||||
success = validate_config_mplane(ru_session);
|
||||
AssertError(success, return false, "[MPLANE] Unable to validate the RU configuration.\n");
|
||||
|
||||
success = commit_config_mplane(ru_session);
|
||||
AssertError(success, return false, "[MPLANE] Unable to commit the RU configuration.\n");
|
||||
success = edit_val_commmit_rpc(ru_session, content);
|
||||
AssertError(success, return false, "[MPLANE] Unable to continue.\n");
|
||||
free(content);
|
||||
}
|
||||
|
||||
const char *usage_state = get_ru_xml_node(operational_ds, "usage-state");
|
||||
@@ -203,3 +216,15 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pm_conf(ru_session_t *ru_session, const char *active)
|
||||
{
|
||||
char *content = get_pm_content(ru_session, active);
|
||||
|
||||
bool success = edit_val_commmit_rpc(ru_session, content);
|
||||
AssertError(success, return false, "[MPLANE] Cannot continue.\n");
|
||||
|
||||
free(content);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,4 +29,6 @@ bool init_mplane(ru_session_list_t *ru_session_list);
|
||||
|
||||
bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus);
|
||||
|
||||
bool pm_conf(ru_session_t *ru_session, const char *active);
|
||||
|
||||
#endif /* OAI_MPLANE_H */
|
||||
|
||||
@@ -33,7 +33,7 @@ static void free_match_list(char **match_list, size_t count)
|
||||
free(match_list);
|
||||
}
|
||||
|
||||
static void fix_benetel_setting(xran_mplane_t *xran_mplane, const uint32_t interface_mtu, const int16_t first_iq_width, const int max_num_ant)
|
||||
static void fix_benetel_setting(xran_mplane_t *xran_mplane, const uint32_t interface_mtu, const int16_t first_iq_width, const int max_num_ant, const char *model_name)
|
||||
{
|
||||
if (interface_mtu == 1500) {
|
||||
MP_LOG_I("Interface MTU %d unreliable/not correctly reported by Benetel O-RU, hardcoding to 9600.\n", interface_mtu);
|
||||
@@ -50,6 +50,14 @@ static void fix_benetel_setting(xran_mplane_t *xran_mplane, const uint32_t inter
|
||||
}
|
||||
|
||||
xran_mplane->prach_offset = max_num_ant;
|
||||
|
||||
if (strcasecmp(model_name, "RAN550") == 0) {
|
||||
xran_mplane->max_tx_gain = 24.0;
|
||||
} else if (strcasecmp(model_name, "RAN650") == 0) {
|
||||
xran_mplane->max_tx_gain = 35.0;
|
||||
} else {
|
||||
assert(false && "[MPLANE] Unknown Benetel model name.\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_t *xran_mplane)
|
||||
@@ -61,7 +69,7 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_
|
||||
xran_mplane->ru_mac_addr = get_ru_xml_node(buffer, "mac-address"); // TODO: support for VVDN, as it defines multiple MAC addresses
|
||||
|
||||
// MTU
|
||||
const uint32_t interface_mtu = (uint32_t)atoi(get_ru_xml_node(buffer, "interface-mtu"));
|
||||
const uint32_t interface_mtu = (uint32_t)atoi(get_ru_xml_node(buffer, "l2-mtu"));
|
||||
|
||||
// IQ bitwidth
|
||||
char **match_list = NULL;
|
||||
@@ -91,8 +99,25 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_
|
||||
// RU port ID
|
||||
xran_mplane->ru_port = 0;
|
||||
|
||||
// Frame structure
|
||||
match_list = NULL;
|
||||
count = 0;
|
||||
get_ru_xml_list(buffer, "supported-frame-structures", &match_list, &count);
|
||||
xran_mplane->frame_str = (int16_t)atoi((char *)match_list[0]);
|
||||
free_match_list(match_list, count);
|
||||
|
||||
// Managed delay support
|
||||
const char *managed_delay = get_ru_xml_node(buffer, "managed-delay-support");
|
||||
xran_mplane->managed_delay = (strcasecmp(managed_delay, "NON_MANAGED") == 0) ? false : true;
|
||||
|
||||
// Store the max gain
|
||||
xran_mplane->max_tx_gain = (double)atof(get_ru_xml_node(buffer, "max-gain"));
|
||||
|
||||
// Model name
|
||||
const char *model_name = get_ru_xml_node(buffer, "model-name");
|
||||
|
||||
if (strcasecmp(ru_vendor, "BENETEL") == 0 /* || strcmp(ru_vendor, "VVDN-LPRU") == 0 || strcmp(ru_vendor, "Metanoia") == 0 */) {
|
||||
fix_benetel_setting(xran_mplane, interface_mtu, first_iq_width, max_num_ant);
|
||||
fix_benetel_setting(xran_mplane, interface_mtu, first_iq_width, max_num_ant, model_name);
|
||||
} else {
|
||||
AssertError(false, return false, "[MPLANE] %s RU currently not supported.\n", ru_vendor);
|
||||
}
|
||||
@@ -109,7 +134,8 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_
|
||||
DU port ID %d\n\
|
||||
Band sector ID %d\n\
|
||||
CC ID %d\n\
|
||||
RU port ID %d\n",
|
||||
RU port ID %d\n\
|
||||
max Tx gain %.1f\n",
|
||||
xran_mplane->ru_mac_addr,
|
||||
xran_mplane->mtu,
|
||||
xran_mplane->iq_width,
|
||||
@@ -121,7 +147,8 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_
|
||||
xran_mplane->du_port,
|
||||
xran_mplane->band_sector,
|
||||
xran_mplane->ccid,
|
||||
xran_mplane->ru_port);
|
||||
xran_mplane->ru_port,
|
||||
xran_mplane->max_tx_gain);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -155,3 +182,23 @@ bool get_uplane_info(const char *buffer, ru_mplane_config_t *ru_mplane_config)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_pm_object_list(const char *buffer, pm_stats_t *pm_stats)
|
||||
{
|
||||
const char *ru_vendor = get_ru_xml_node(buffer, "mfg-name");
|
||||
if (strcasecmp(ru_vendor, "BENETEL") == 0) {
|
||||
pm_stats->start_up_timing = false;
|
||||
} else {
|
||||
pm_stats->start_up_timing = true;
|
||||
}
|
||||
|
||||
// Rx window
|
||||
get_ru_xml_list(buffer, "rx-window-objects", &pm_stats->rx_window_meas, &pm_stats->rx_num);
|
||||
|
||||
// Tx
|
||||
get_ru_xml_list(buffer, "tx-stats-objects", &pm_stats->tx_meas, &pm_stats->tx_num);
|
||||
|
||||
MP_LOG_I("Successfully retreived all performance measurement names.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,10 @@ typedef struct {
|
||||
uint8_t band_sector;
|
||||
uint8_t ccid;
|
||||
uint8_t ru_port;
|
||||
int16_t frame_str; // might be needed in the future xran releases
|
||||
bool managed_delay;
|
||||
|
||||
double max_tx_gain;
|
||||
|
||||
} xran_mplane_t;
|
||||
|
||||
@@ -78,11 +82,26 @@ typedef struct {
|
||||
} ru_mplane_config_t;
|
||||
|
||||
typedef struct {
|
||||
// activation if required at start-up timing
|
||||
bool start_up_timing;
|
||||
|
||||
size_t rx_num;
|
||||
char **rx_window_meas;
|
||||
|
||||
size_t tx_num;
|
||||
char **tx_meas;
|
||||
|
||||
} pm_stats_t;
|
||||
|
||||
typedef struct {
|
||||
char *username;
|
||||
char *ru_ip_add;
|
||||
ru_mplane_config_t ru_mplane_config;
|
||||
void *session;
|
||||
void *ctx;
|
||||
xran_mplane_t xran_mplane;
|
||||
ru_notif_t ru_notif;
|
||||
pm_stats_t pm_stats;
|
||||
|
||||
} ru_session_t;
|
||||
|
||||
@@ -97,4 +116,6 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_
|
||||
|
||||
bool get_uplane_info(const char *buffer, ru_mplane_config_t *ru_mplane_config);
|
||||
|
||||
bool get_pm_object_list(const char *buffer, pm_stats_t *pm_stats);
|
||||
|
||||
#endif /* RU_MPLANE_API_H */
|
||||
|
||||
@@ -54,6 +54,37 @@ static void notif_clb_v1(struct nc_session *session, const struct nc_notif *noti
|
||||
recv_notif_v1(notif, answer);
|
||||
}
|
||||
#elif MPLANE_V2
|
||||
static void log_v2_pm_info(const char *ru_ip_add, struct lyd_node_inner *stats)
|
||||
{
|
||||
struct lyd_node *child, *field = NULL;
|
||||
size_t len = 0;
|
||||
char *meas_list[8], *count_list[8] = {};
|
||||
|
||||
LY_LIST_FOR(stats->child, child) {
|
||||
// const char *type = child->schema->name; // e.g. "rx-window-stats", "tx-stats"
|
||||
struct lyd_node_inner *stats_inner = (struct lyd_node_inner *)child;
|
||||
LY_LIST_FOR(stats_inner->child, field) {
|
||||
if (strcmp(field->schema->name, "measurement-object") == 0) {
|
||||
meas_list[len] = (char *)lyd_get_value(field);
|
||||
} else if (strcmp(field->schema->name, "count") == 0) {
|
||||
count_list[len] = (char *)lyd_get_value(field);
|
||||
len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MP_LOG_I("[PM: \"%s\"][%s %7s][%s %7s][%s %7s][%s %7s][%s %7s][%s %7s][%s %7s][%s %7s]\n",
|
||||
ru_ip_add,
|
||||
meas_list[0], count_list[0],
|
||||
meas_list[1], count_list[1],
|
||||
meas_list[2], count_list[2],
|
||||
meas_list[3], count_list[3],
|
||||
meas_list[4], count_list[4],
|
||||
meas_list[5], count_list[5],
|
||||
meas_list[6], count_list[6],
|
||||
meas_list[7], count_list[7]);
|
||||
}
|
||||
|
||||
static void recv_notif_v2(struct lyd_node_inner *op, ru_notif_t *answer)
|
||||
{
|
||||
const char *notif = op->schema->name;
|
||||
@@ -92,9 +123,14 @@ static void notif_clb_v2(struct nc_session *session, const struct lyd_node *envp
|
||||
char *subs_reply = NULL;
|
||||
lyd_print_mem(&subs_reply, op, output_format, LYD_PRINT_WITHSIBLINGS);
|
||||
const char *ru_ip_add = nc_session_get_host(session);
|
||||
struct lyd_node_inner *op_inner = (struct lyd_node_inner *)op;
|
||||
if (strcmp(op_inner->schema->name, "measurement-result-stats") == 0) {
|
||||
log_v2_pm_info(ru_ip_add, op_inner);
|
||||
return;
|
||||
}
|
||||
MP_LOG_I("Received notification from RU \"%s\" at (%s)\n%s\n", ru_ip_add, ((struct lyd_node_opaq *)lyd_child(envp))->value, subs_reply);
|
||||
|
||||
recv_notif_v2((struct lyd_node_inner *)op, answer);
|
||||
recv_notif_v2(op_inner, answer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ static void find_ru_xml_list(xmlNode *node, const char *filter, char ***match_li
|
||||
xmlNode *name_node = NULL;
|
||||
|
||||
for (xmlNode *cur_node2 = cur_node->children; cur_node2; cur_node2 = cur_node2->next) {
|
||||
if (cur_node2->type == XML_ELEMENT_NODE && strcmp((const char *)cur_node2->name, "name") == 0) {
|
||||
const char *name_node_str = (const char *)cur_node2->name;
|
||||
if (cur_node2->type == XML_ELEMENT_NODE && (strcmp(name_node_str, "name") == 0 || strcmp(name_node_str, "measurement-object") == 0)) {
|
||||
name_node = cur_node2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -23,13 +23,14 @@
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
#define VERIFY_SUCCESS(var, message, args...) AssertError(var, return false, message, ##args)
|
||||
const char *scs_name[] = {"KHZ_15", "KHZ_30", "KHZ_60", "KHZ_120", "KHZ_240", NULL};
|
||||
|
||||
#ifdef MPLANE_V2
|
||||
static bool create_cu_interface_v2(struct ly_ctx **ctx, const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root)
|
||||
static bool create_cu_interface_v2(const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
|
||||
ret = lyd_new_path(NULL, *ctx, "/ietf-interfaces:interfaces", NULL, 0, root);
|
||||
ret = lyd_new_path(NULL, (struct ly_ctx *)ru_session->ctx, "/ietf-interfaces:interfaces", NULL, 0, root);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"interfaces\" node.\n");
|
||||
|
||||
struct lyd_node *interface_node = NULL;
|
||||
@@ -43,7 +44,7 @@ static bool create_cu_interface_v2(struct ly_ctx **ctx, const ru_session_t *ru_s
|
||||
ret = lyd_new_term(interface_node, NULL, "enabled", "true", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"enabled\" node.\n");
|
||||
|
||||
const struct lys_module *oran_int_mod = ly_ctx_get_module_implemented(*ctx, "o-ran-interfaces");
|
||||
const struct lys_module *oran_int_mod = ly_ctx_get_module_implemented((struct ly_ctx *)ru_session->ctx, "o-ran-interfaces");
|
||||
VERIFY_SUCCESS(oran_int_mod != NULL, "[MPLANE] Failed to get \"o-ran-interfaces\" module.\n");
|
||||
|
||||
struct lyd_node *base_int = NULL;
|
||||
@@ -63,11 +64,11 @@ static bool create_cu_interface_v2(struct ly_ctx **ctx, const ru_session_t *ru_s
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool create_proc_elem_v2(struct ly_ctx **ctx, const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root)
|
||||
static bool create_proc_elem_v2(const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
|
||||
ret = lyd_new_path(NULL, *ctx, "/o-ran-processing-element:processing-elements", NULL, 0, root);
|
||||
ret = lyd_new_path(NULL, (struct ly_ctx *)ru_session->ctx, "/o-ran-processing-element:processing-elements", NULL, 0, root);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"processing-elements\" node.\n");
|
||||
|
||||
ret = lyd_new_term(*root, NULL, "transport-session-type", "ETH-INTERFACE", 0, NULL);
|
||||
@@ -104,20 +105,42 @@ static bool create_proc_elem_v2(struct ly_ctx **ctx, const ru_session_t *ru_sess
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool fill_uplane_ch_v2(const xran_mplane_t *xran_mplane, const size_t idx, struct lyd_node **root)
|
||||
typedef enum { UP_CH_RX, UP_CH_TX } uplane_dir_t;
|
||||
|
||||
static LY_ERR fill_uplane_ch_common_v2(const uplane_dir_t dir, const xran_mplane_t *xran_mplane, const openair0_config_t *oai, const size_t idx, struct lyd_node **root)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
|
||||
ret = lyd_new_term(*root, NULL, "cp-length", "0", 0, NULL);
|
||||
char frame_str[8];
|
||||
snprintf(frame_str, sizeof(frame_str), "%d", (oai->split7.fftSize << 4) + oai->nr_scs_for_raster); // 3GPP TS 38.211
|
||||
ret = lyd_new_term(*root, NULL, "frame-structure", frame_str, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"frame-structure\" node.\n");
|
||||
|
||||
// EXTENDED not supported
|
||||
// 3GPP TS 38.211
|
||||
const char cp_type[] = "NORMAL";
|
||||
ret = lyd_new_term(*root, NULL, "cp-type", cp_type, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"cp-type\" node.\n");
|
||||
|
||||
char cp_len[8];
|
||||
snprintf(cp_len, sizeof(cp_len), "%d", oai->split7.cp_prefix0);
|
||||
ret = lyd_new_term(*root, NULL, "cp-length", cp_len, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"cp-length\" node.\n");
|
||||
|
||||
ret = lyd_new_term(*root, NULL, "cp-length-other", "0", 0, NULL);
|
||||
|
||||
char cp_len_other[8];
|
||||
snprintf(cp_len_other, sizeof(cp_len_other), "%d", oai->split7.cp_prefix_other);
|
||||
ret = lyd_new_term(*root, NULL, "cp-length-other", cp_len_other, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"cp-length-other\" node.\n");
|
||||
|
||||
// to we actually store this from DU config file?
|
||||
ret = lyd_new_term(*root, NULL, "offset-to-absolute-frequency-center", "0", 0, NULL);
|
||||
|
||||
char freq_offset[8];
|
||||
if (dir == UP_CH_RX) {
|
||||
snprintf(freq_offset, sizeof(freq_offset), "%d", oai->split7.ul_k0[oai->nr_scs_for_raster]);
|
||||
} else {
|
||||
snprintf(freq_offset, sizeof(freq_offset), "%d", oai->split7.dl_k0[oai->nr_scs_for_raster]);
|
||||
}
|
||||
ret = lyd_new_term(*root, NULL, "offset-to-absolute-frequency-center", freq_offset, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"offset-to-absolute-frequency-center\" node.\n");
|
||||
|
||||
|
||||
struct lyd_node *compression_node = NULL;
|
||||
ret = lyd_new_inner(*root, NULL, "compression", 0, &compression_node);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"compression\" node.\n");
|
||||
@@ -126,15 +149,15 @@ static bool fill_uplane_ch_v2(const xran_mplane_t *xran_mplane, const size_t idx
|
||||
snprintf(iq_width_str, sizeof(iq_width_str), "%d", xran_mplane->iq_width);
|
||||
ret = lyd_new_term(compression_node, NULL, "iq-bitwidth", iq_width_str, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"iq-bitwidth\" node.\n");
|
||||
|
||||
|
||||
if (xran_mplane->iq_width < 16) {
|
||||
ret = lyd_new_term(compression_node, NULL, "compression-type", "STATIC", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"compression-type\" node.\n");
|
||||
|
||||
|
||||
// ret = lyd_new_term(compression_node, NULL, "compression-method", "BLOCK_FLOATING_POINT", 0, NULL);
|
||||
// VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"compression-method\" node.\n");
|
||||
}
|
||||
|
||||
|
||||
struct lyd_node *eaxc_conf = NULL;
|
||||
ret = lyd_new_inner(*root, NULL, "e-axcid", 0, &eaxc_conf);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"e-axcid\" node.\n");
|
||||
@@ -143,12 +166,12 @@ static bool fill_uplane_ch_v2(const xran_mplane_t *xran_mplane, const size_t idx
|
||||
snprintf(eaxc_id, sizeof(eaxc_id), "%ld", idx);
|
||||
ret = lyd_new_term(eaxc_conf, NULL, "eaxc-id", eaxc_id, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"eaxc-id\" node.\n");
|
||||
|
||||
|
||||
char du_port_bitmask[16];
|
||||
snprintf(du_port_bitmask, sizeof(du_port_bitmask), "%d", xran_mplane->du_port_bitmask);
|
||||
ret = lyd_new_term(eaxc_conf, NULL, "o-du-port-bitmask", du_port_bitmask, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"o-du-port-bitmask\" node.\n");
|
||||
|
||||
|
||||
char band_sector_bitmask[8];
|
||||
snprintf(band_sector_bitmask, sizeof(band_sector_bitmask), "%d", xran_mplane->band_sector_bitmask);
|
||||
ret = lyd_new_term(eaxc_conf, NULL, "band-sector-bitmask", band_sector_bitmask, 0, NULL);
|
||||
@@ -164,15 +187,50 @@ static bool fill_uplane_ch_v2(const xran_mplane_t *xran_mplane, const size_t idx
|
||||
ret = lyd_new_term(eaxc_conf, NULL, "ru-port-bitmask", ru_port_bitmask, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ru-port-bitmask\" node.\n");
|
||||
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
static bool fill_uplane_ch_rx_v2(const xran_mplane_t *xran_mplane, const openair0_config_t *oai, const size_t idx, struct lyd_node **root)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
|
||||
ret = fill_uplane_ch_common_v2(UP_CH_RX, xran_mplane, oai, idx, root);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create common nodes.\n");
|
||||
|
||||
const char *managed_delay = xran_mplane->managed_delay ? "true" : "false";
|
||||
ret = lyd_new_term(*root, NULL, "non-time-managed-delay-enabled", managed_delay, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"non-time-managed-delay-enabled\" node.\n");
|
||||
|
||||
struct lyd_node *fft_offset = NULL;
|
||||
ret = lyd_new_list(*root, NULL, "ul-fft-sampling-offsets", 0, &fft_offset, scs_name[oai->nr_scs_for_raster]);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ul-fft-sampling-offsets\" node.\n");
|
||||
|
||||
// Note: set of allowed values is restricted by SCS derived from values in supported-frame-structures.
|
||||
char ul_fft_offset[8];
|
||||
const int frame = (oai->split7.fftSize << 4) + oai->nr_scs_for_raster;
|
||||
snprintf(ul_fft_offset, sizeof(ul_fft_offset), "%d", frame - xran_mplane->frame_str);
|
||||
ret = lyd_new_term(fft_offset, NULL, "ul-fft-sampling-offset", ul_fft_offset, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ul-fft-sampling-offset\" node.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, const char *u_proc_elem, struct lyd_node **root)
|
||||
static bool fill_uplane_ch_tx_v2(const xran_mplane_t *xran_mplane, const openair0_config_t *oai, const size_t idx, struct lyd_node **root)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
|
||||
ret = fill_uplane_ch_common_v2(UP_CH_TX, xran_mplane, oai, idx, root);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create common nodes.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool create_uplane_conf_v2(const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, const char *u_proc_elem, struct lyd_node **root)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
bool success = true;
|
||||
|
||||
ret = lyd_new_path(NULL, *ctx, "/o-ran-uplane-conf:user-plane-configuration", NULL, 0, root);
|
||||
ret = lyd_new_path(NULL, (struct ly_ctx *)ru_session->ctx, "/o-ran-uplane-conf:user-plane-configuration", NULL, 0, root);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"user-plane-configuration\" node.\n");
|
||||
|
||||
if (ru_session->ru_mplane_config.rx_carriers.num != 1 || ru_session->ru_mplane_config.tx_carriers.num !=1)
|
||||
@@ -204,7 +262,8 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se
|
||||
ret = lyd_new_term(rx_carrier_node, NULL, "downlink-sfn-offset", "0", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"downlink-sfn-offset\" node.\n");
|
||||
|
||||
// oai->rx_gain_offset is this the correction? if yes, test it later
|
||||
// gain offset applied uniformly across all array elements or layers
|
||||
// needs to be within <gain-correction-range>
|
||||
ret = lyd_new_term(rx_carrier_node, NULL, "gain-correction", "0", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"gain-correction\" node.\n");
|
||||
|
||||
@@ -234,8 +293,12 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se
|
||||
ret = lyd_new_term(tx_carrier_node, NULL, "channel-bandwidth", tx_bw, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"channel-bandwidth\" node.\n");
|
||||
|
||||
// oai->tx_gain to be tested
|
||||
ret = lyd_new_term(tx_carrier_node, NULL, "gain", "0", 0, NULL);
|
||||
// oai->tx_gain takes the value of att_tx from the RU section of gNB config file
|
||||
// we assume the same gain is applied to all channels; same as above for the frequency
|
||||
const double tx_gain_value = ((oai->tx_gain[0] * 10000) < ru_session->xran_mplane.max_tx_gain) ? (oai->tx_gain[0] * 10000) : ru_session->xran_mplane.max_tx_gain;
|
||||
char tx_gain_str[8];
|
||||
snprintf(tx_gain_str, sizeof(tx_gain_str), "%.f", tx_gain_value);
|
||||
ret = lyd_new_term(tx_carrier_node, NULL, "gain", tx_gain_str, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"gain\" node.\n");
|
||||
|
||||
ret = lyd_new_term(tx_carrier_node, NULL, "downlink-radio-frame-offset", "0", 0, NULL);
|
||||
@@ -254,7 +317,7 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se
|
||||
ret = lyd_new_list(*root, NULL, "low-level-rx-endpoints", 0, &pusch_node, ru_session->ru_mplane_config.rx_endpoints.name[i]);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-endpoints\" node.\n");
|
||||
|
||||
success = fill_uplane_ch_v2(&ru_session->xran_mplane, i, &pusch_node);
|
||||
success = fill_uplane_ch_rx_v2(&ru_session->xran_mplane, oai, i, &pusch_node);
|
||||
VERIFY_SUCCESS(success, "[MPLANE] Failed to fill \"low-level-rx-endpoints\" node for %s.\n", ru_session->ru_mplane_config.rx_endpoints.name[i]);
|
||||
|
||||
const size_t prach_endpoint_name_offset = i + (ru_session->ru_mplane_config.rx_endpoints.num / 2);
|
||||
@@ -262,7 +325,7 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se
|
||||
ret = lyd_new_list(*root, NULL, "low-level-rx-endpoints", 0, &prach_node, ru_session->ru_mplane_config.rx_endpoints.name[prach_endpoint_name_offset]);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-endpoints\" node.\n");
|
||||
|
||||
success = fill_uplane_ch_v2(&ru_session->xran_mplane, i + ru_session->xran_mplane.prach_offset, &prach_node);
|
||||
success = fill_uplane_ch_rx_v2(&ru_session->xran_mplane, oai, i + ru_session->xran_mplane.prach_offset, &prach_node);
|
||||
VERIFY_SUCCESS(success, "[MPLANE] Failed to fill \"low-level-rx-endpoints\" node for %s.\n", ru_session->ru_mplane_config.rx_endpoints.name[prach_endpoint_name_offset]);
|
||||
}
|
||||
|
||||
@@ -273,7 +336,7 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se
|
||||
ret = lyd_new_list(*root, NULL, "low-level-tx-endpoints", 0, &pdsch_node, ru_session->ru_mplane_config.tx_endpoints.name[i]);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-tx-endpoints\" node.\n");
|
||||
|
||||
success = fill_uplane_ch_v2(&ru_session->xran_mplane, i, &pdsch_node);
|
||||
success = fill_uplane_ch_tx_v2(&ru_session->xran_mplane, oai, i, &pdsch_node);
|
||||
VERIFY_SUCCESS(success, "[MPLANE] Failed to fill \"low-level-tx-endpoints\" node for %s.\n", ru_session->ru_mplane_config.tx_endpoints.name[i]);
|
||||
}
|
||||
|
||||
@@ -333,9 +396,59 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool create_pm_conf_v2(const ru_session_t *ru_session, const char *active, struct lyd_node **root)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
|
||||
ret = lyd_new_path(NULL, (struct ly_ctx *)ru_session->ctx, "/o-ran-performance-management:performance-measurement-objects", NULL, 0, root);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"performance-measurement-objects\" node.\n");
|
||||
|
||||
ret = lyd_new_term(*root, NULL, "notification-interval", "10", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"notification-interval\" node.\n");
|
||||
|
||||
ret = lyd_new_term(*root, NULL, "rx-window-measurement-interval", "10", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"rx-window-measurement-interval\" node.\n");
|
||||
|
||||
ret = lyd_new_term(*root, NULL, "tx-measurement-interval", "10", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"tx-measurement-interval\" node.\n");
|
||||
|
||||
for (size_t i = 0; i < ru_session->pm_stats.rx_num; i++) {
|
||||
struct lyd_node *rx_window_meas_objects = NULL;
|
||||
ret = lyd_new_list(*root, NULL, "rx-window-measurement-objects", 0, &rx_window_meas_objects, ru_session->pm_stats.rx_window_meas[i]);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"rx-window-measurement-objects\" node.\n");
|
||||
|
||||
ret = lyd_new_term(rx_window_meas_objects, NULL, "active", active, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"active\" node.\n");
|
||||
|
||||
ret = lyd_new_term(rx_window_meas_objects, NULL, "object-unit", "RU", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"object-unit\" node.\n");
|
||||
|
||||
ret = lyd_new_term(rx_window_meas_objects, NULL, "report-info", "COUNT", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"report-info\" node.\n");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ru_session->pm_stats.tx_num; i++) {
|
||||
struct lyd_node *tx_meas_objects = NULL;
|
||||
ret = lyd_new_list(*root, NULL, "tx-measurement-objects", 0, &tx_meas_objects, ru_session->pm_stats.tx_meas[i]);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"tx-measurement-objects\" node.\n");
|
||||
|
||||
ret = lyd_new_term(tx_meas_objects, NULL, "active", active, 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"active\" node.\n");
|
||||
|
||||
ret = lyd_new_term(tx_meas_objects, NULL, "object-unit", "RU", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"object-unit\" node.\n");
|
||||
|
||||
ret = lyd_new_term(tx_meas_objects, NULL, "report-info", "COUNT", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"report-info\" node.\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result)
|
||||
bool configure_ru_from_yang(const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
@@ -357,12 +470,12 @@ bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session,
|
||||
struct lyd_node *cu_interface = NULL;
|
||||
char int_name[12];
|
||||
snprintf(int_name, sizeof(int_name), "INTERFACE_%ld", i);
|
||||
success = create_cu_interface_v2(ctx, ru_session, i, int_name, &cu_interface);
|
||||
success = create_cu_interface_v2(ru_session, i, int_name, &cu_interface);
|
||||
VERIFY_SUCCESS(success, "[MPLANE] Cannot create CU-plane interface.\n");
|
||||
|
||||
// <o-ran-processing-element>
|
||||
struct lyd_node *proc_elem = NULL;
|
||||
success = create_proc_elem_v2(ctx, ru_session, i, int_name, &proc_elem);
|
||||
success = create_proc_elem_v2(ru_session, i, int_name, &proc_elem);
|
||||
VERIFY_SUCCESS(success, "[MPLANE] Cannot create CU-plane processing element.\n");
|
||||
|
||||
ret = lyd_merge_siblings(&all_merge, cu_interface, 0);
|
||||
@@ -376,17 +489,49 @@ bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session,
|
||||
|
||||
// <o-ran-uplane-conf>
|
||||
struct lyd_node *uplane_conf = NULL;
|
||||
success = create_uplane_conf_v2(ctx, ru_session, oai, num_rus, "PLANE_0", &uplane_conf);
|
||||
success = create_uplane_conf_v2(ru_session, oai, num_rus, "PLANE_0", &uplane_conf);
|
||||
VERIFY_SUCCESS(success, "[MPLANE] Cannot create U-plane configuration.\n");
|
||||
|
||||
ret = lyd_merge_siblings(&uplane_conf, all_merge, 0);
|
||||
|
||||
ret = lyd_merge_siblings(&all_merge, uplane_conf, 0);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Cannot merge CU-plane interface, processing element and U-plane configuration.\n");
|
||||
|
||||
lyd_print_mem(result, uplane_conf, LYD_XML, LYD_PRINT_WITHSIBLINGS);
|
||||
// <o-ran-pm>
|
||||
struct lyd_node *pm_conf = NULL;
|
||||
if (ru_session->pm_stats.start_up_timing) {
|
||||
success = create_pm_conf_v2(ru_session, "true", &pm_conf);
|
||||
VERIFY_SUCCESS(success, "[MPLANE] Cannot create PM activation.\n");
|
||||
} else {
|
||||
success = create_pm_conf_v2(ru_session, "false", &pm_conf);
|
||||
VERIFY_SUCCESS(success, "[MPLANE] Cannot create PM deactivation.\n");
|
||||
}
|
||||
|
||||
ret = lyd_merge_siblings(&all_merge, pm_conf, 0);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Cannot merge CU-plane interface, processing element, U-plane configuration and PM configuration.\n");
|
||||
|
||||
lyd_print_mem(result, all_merge, LYD_XML, LYD_PRINT_WITHSIBLINGS);
|
||||
|
||||
lyd_free_siblings(all_merge);
|
||||
lyd_free_siblings(uplane_conf);
|
||||
lyd_free_siblings(pm_conf);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *get_pm_content(const ru_session_t *ru_session, const char *active)
|
||||
{
|
||||
bool success = false;
|
||||
char *content = NULL;
|
||||
|
||||
#ifdef MPLANE_V1
|
||||
VERIFY_SUCCESS(success, "[MPLANE] To be implemented and tested.\n");
|
||||
#elif defined MPLANE_V2
|
||||
struct lyd_node *pm_conf = NULL;
|
||||
success = create_pm_conf_v2(ru_session, active, &pm_conf);
|
||||
AssertError(success, return false, "[MPLANE] Cannot create PM configuration.\n");
|
||||
lyd_print_mem(&content, pm_conf, LYD_XML, LYD_PRINT_WITHSIBLINGS);
|
||||
lyd_free_siblings(pm_conf);
|
||||
#endif
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include <libyang/libyang.h>
|
||||
|
||||
bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result);
|
||||
bool configure_ru_from_yang(const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result);
|
||||
|
||||
char *get_pm_content(const ru_session_t *ru_session, const char *active);
|
||||
|
||||
#endif /* CREATE_MPLANE_YANG_CONFIG_H */
|
||||
|
||||
@@ -95,8 +95,10 @@ static bool load_from_operational_ds(xmlNode *node, ru_session_t *ru_session, st
|
||||
return false;
|
||||
}
|
||||
|
||||
bool load_yang_models(ru_session_t *ru_session, const char *buffer, struct ly_ctx **ctx)
|
||||
bool load_yang_models(ru_session_t *ru_session, const char *buffer)
|
||||
{
|
||||
struct ly_ctx **ctx = (struct ly_ctx **)&ru_session->ctx;
|
||||
|
||||
// Initialize the xml file
|
||||
size_t len = strlen(buffer) + 1;
|
||||
xmlDoc *doc = xmlReadMemory(buffer, len, NULL, NULL, 0);
|
||||
@@ -114,7 +116,7 @@ bool load_yang_models(ru_session_t *ru_session, const char *buffer, struct ly_ct
|
||||
1) the yang models order is not good - the dependancy models have to be loaded first
|
||||
2) earlier O-RAN yang versions (e.g. v4) is not properly defined (i.e. optional parameters should not be included by default) */
|
||||
const char *yang_dir = YANG_MODELS;
|
||||
const char *yang_models[] = {"ietf-interfaces", "iana-if-type", "ietf-ip", "iana-hardware", "ietf-hardware", "o-ran-interfaces", "o-ran-module-cap", "o-ran-compression-factors", "o-ran-processing-element", "o-ran-uplane-conf"};
|
||||
const char *yang_models[] = {"ietf-interfaces", "iana-if-type", "ietf-ip", "iana-hardware", "ietf-hardware", "o-ran-interfaces", "o-ran-module-cap", "o-ran-compression-factors", "o-ran-processing-element", "o-ran-uplane-conf", "ietf-netconf-acm", "ietf-crypto-types", "o-ran-file-management", "o-ran-performance-management"};
|
||||
|
||||
#ifdef MPLANE_V1
|
||||
*ctx = ly_ctx_new(yang_dir, 0);
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
|
||||
#include <libyang/libyang.h>
|
||||
|
||||
bool load_yang_models(ru_session_t *ru_session, const char *buffer, struct ly_ctx **ctx);
|
||||
bool load_yang_models(ru_session_t *ru_session, const char *buffer);
|
||||
|
||||
#endif /* GET_MPLANE_YANG_MODELS_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,440 @@
|
||||
module ietf-netconf-acm {
|
||||
|
||||
namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-acm";
|
||||
|
||||
prefix nacm;
|
||||
|
||||
import ietf-yang-types {
|
||||
prefix yang;
|
||||
}
|
||||
|
||||
organization
|
||||
"IETF NETCONF (Network Configuration) Working Group";
|
||||
|
||||
contact
|
||||
"WG Web: <https://datatracker.ietf.org/wg/netconf/>
|
||||
WG List: <mailto:netconf@ietf.org>
|
||||
Author: Andy Bierman
|
||||
<mailto:andy@yumaworks.com>
|
||||
Author: Martin Bjorklund
|
||||
<mailto:mbj@tail-f.com>";
|
||||
|
||||
description
|
||||
"Network Configuration Access Control Model.
|
||||
Copyright (c) 2012 - 2018 IETF Trust and the persons
|
||||
identified as authors of the code. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or
|
||||
without modification, is permitted pursuant to, and subject
|
||||
to the license terms contained in, the Simplified BSD
|
||||
License set forth in Section 4.c of the IETF Trust's
|
||||
Legal Provisions Relating to IETF Documents
|
||||
(https://trustee.ietf.org/license-info).
|
||||
This version of this YANG module is part of RFC 8341; see
|
||||
the RFC itself for full legal notices.";
|
||||
|
||||
revision "2018-02-14" {
|
||||
description
|
||||
"Added support for YANG 1.1 actions and notifications tied to
|
||||
data nodes. Clarified how NACM extensions can be used by
|
||||
other data models.";
|
||||
reference
|
||||
"RFC 8341: Network Configuration Access Control Model";
|
||||
}
|
||||
|
||||
revision "2012-02-22" {
|
||||
description
|
||||
"Initial version.";
|
||||
reference
|
||||
"RFC 6536: Network Configuration Protocol (NETCONF)
|
||||
Access Control Model";
|
||||
}
|
||||
|
||||
/*
|
||||
* Extension statements
|
||||
*/
|
||||
|
||||
extension default-deny-write {
|
||||
description
|
||||
"Used to indicate that the data model node
|
||||
represents a sensitive security system parameter.
|
||||
If present, the NETCONF server will only allow the designated
|
||||
'recovery session' to have write access to the node. An
|
||||
explicit access control rule is required for all other users.
|
||||
If the NACM module is used, then it must be enabled (i.e.,
|
||||
/nacm/enable-nacm object equals 'true'), or this extension
|
||||
is ignored.
|
||||
The 'default-deny-write' extension MAY appear within a data
|
||||
definition statement. It is ignored otherwise.";
|
||||
}
|
||||
|
||||
extension default-deny-all {
|
||||
description
|
||||
"Used to indicate that the data model node
|
||||
controls a very sensitive security system parameter.
|
||||
If present, the NETCONF server will only allow the designated
|
||||
'recovery session' to have read, write, or execute access to
|
||||
the node. An explicit access control rule is required for all
|
||||
other users.
|
||||
If the NACM module is used, then it must be enabled (i.e.,
|
||||
/nacm/enable-nacm object equals 'true'), or this extension
|
||||
is ignored.
|
||||
The 'default-deny-all' extension MAY appear within a data
|
||||
definition statement, 'rpc' statement, or 'notification'
|
||||
statement. It is ignored otherwise.";
|
||||
}
|
||||
|
||||
/*
|
||||
* Derived types
|
||||
*/
|
||||
|
||||
typedef user-name-type {
|
||||
type string {
|
||||
length "1..max";
|
||||
}
|
||||
description
|
||||
"General-purpose username string.";
|
||||
}
|
||||
|
||||
typedef matchall-string-type {
|
||||
type string {
|
||||
pattern '\*';
|
||||
}
|
||||
description
|
||||
"The string containing a single asterisk '*' is used
|
||||
to conceptually represent all possible values
|
||||
for the particular leaf using this data type.";
|
||||
}
|
||||
|
||||
typedef access-operations-type {
|
||||
type bits {
|
||||
bit create {
|
||||
description
|
||||
"Any protocol operation that creates a
|
||||
new data node.";
|
||||
}
|
||||
bit read {
|
||||
description
|
||||
"Any protocol operation or notification that
|
||||
returns the value of a data node.";
|
||||
}
|
||||
bit update {
|
||||
description
|
||||
"Any protocol operation that alters an existing
|
||||
data node.";
|
||||
}
|
||||
bit delete {
|
||||
description
|
||||
"Any protocol operation that removes a data node.";
|
||||
}
|
||||
bit exec {
|
||||
description
|
||||
"Execution access to the specified protocol operation.";
|
||||
}
|
||||
}
|
||||
description
|
||||
"Access operation.";
|
||||
}
|
||||
|
||||
typedef group-name-type {
|
||||
type string {
|
||||
length "1..max";
|
||||
pattern '[^\*].*';
|
||||
}
|
||||
description
|
||||
"Name of administrative group to which
|
||||
users can be assigned.";
|
||||
}
|
||||
|
||||
typedef action-type {
|
||||
type enumeration {
|
||||
enum permit {
|
||||
description
|
||||
"Requested action is permitted.";
|
||||
}
|
||||
enum deny {
|
||||
description
|
||||
"Requested action is denied.";
|
||||
}
|
||||
}
|
||||
description
|
||||
"Action taken by the server when a particular
|
||||
rule matches.";
|
||||
}
|
||||
|
||||
typedef node-instance-identifier {
|
||||
type yang:xpath1.0;
|
||||
description
|
||||
"Path expression used to represent a special
|
||||
data node, action, or notification instance-identifier
|
||||
string.
|
||||
A node-instance-identifier value is an
|
||||
unrestricted YANG instance-identifier expression.
|
||||
All the same rules as an instance-identifier apply,
|
||||
except that predicates for keys are optional. If a key
|
||||
predicate is missing, then the node-instance-identifier
|
||||
represents all possible server instances for that key.
|
||||
This XML Path Language (XPath) expression is evaluated in the
|
||||
following context:
|
||||
o The set of namespace declarations are those in scope on
|
||||
the leaf element where this type is used.
|
||||
o The set of variable bindings contains one variable,
|
||||
'USER', which contains the name of the user of the
|
||||
current session.
|
||||
o The function library is the core function library, but
|
||||
note that due to the syntax restrictions of an
|
||||
instance-identifier, no functions are allowed.
|
||||
o The context node is the root node in the data tree.
|
||||
The accessible tree includes actions and notifications tied
|
||||
to data nodes.";
|
||||
}
|
||||
|
||||
/*
|
||||
* Data definition statements
|
||||
*/
|
||||
|
||||
container nacm {
|
||||
nacm:default-deny-all;
|
||||
|
||||
description
|
||||
"Parameters for NETCONF access control model.";
|
||||
|
||||
leaf enable-nacm {
|
||||
type boolean;
|
||||
default "true";
|
||||
description
|
||||
"Enables or disables all NETCONF access control
|
||||
enforcement. If 'true', then enforcement
|
||||
is enabled. If 'false', then enforcement
|
||||
is disabled.";
|
||||
}
|
||||
|
||||
leaf read-default {
|
||||
type action-type;
|
||||
default "permit";
|
||||
description
|
||||
"Controls whether read access is granted if
|
||||
no appropriate rule is found for a
|
||||
particular read request.";
|
||||
}
|
||||
|
||||
leaf write-default {
|
||||
type action-type;
|
||||
default "deny";
|
||||
description
|
||||
"Controls whether create, update, or delete access
|
||||
is granted if no appropriate rule is found for a
|
||||
particular write request.";
|
||||
}
|
||||
|
||||
leaf exec-default {
|
||||
type action-type;
|
||||
default "permit";
|
||||
description
|
||||
"Controls whether exec access is granted if no appropriate
|
||||
rule is found for a particular protocol operation request.";
|
||||
}
|
||||
|
||||
leaf enable-external-groups {
|
||||
type boolean;
|
||||
default "true";
|
||||
description
|
||||
"Controls whether the server uses the groups reported by the
|
||||
NETCONF transport layer when it assigns the user to a set of
|
||||
NACM groups. If this leaf has the value 'false', any group
|
||||
names reported by the transport layer are ignored by the
|
||||
server.";
|
||||
}
|
||||
|
||||
leaf denied-operations {
|
||||
type yang:zero-based-counter32;
|
||||
config false;
|
||||
mandatory true;
|
||||
description
|
||||
"Number of times since the server last restarted that a
|
||||
protocol operation request was denied.";
|
||||
}
|
||||
|
||||
leaf denied-data-writes {
|
||||
type yang:zero-based-counter32;
|
||||
config false;
|
||||
mandatory true;
|
||||
description
|
||||
"Number of times since the server last restarted that a
|
||||
protocol operation request to alter
|
||||
a configuration datastore was denied.";
|
||||
}
|
||||
|
||||
leaf denied-notifications {
|
||||
type yang:zero-based-counter32;
|
||||
config false;
|
||||
mandatory true;
|
||||
description
|
||||
"Number of times since the server last restarted that
|
||||
a notification was dropped for a subscription because
|
||||
access to the event type was denied.";
|
||||
}
|
||||
|
||||
container groups {
|
||||
description
|
||||
"NETCONF access control groups.";
|
||||
|
||||
list group {
|
||||
key name;
|
||||
|
||||
description
|
||||
"One NACM group entry. This list will only contain
|
||||
configured entries, not any entries learned from
|
||||
any transport protocols.";
|
||||
|
||||
leaf name {
|
||||
type group-name-type;
|
||||
description
|
||||
"Group name associated with this entry.";
|
||||
}
|
||||
|
||||
leaf-list user-name {
|
||||
type user-name-type;
|
||||
description
|
||||
"Each entry identifies the username of
|
||||
a member of the group associated with
|
||||
this entry.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list rule-list {
|
||||
key name;
|
||||
ordered-by user;
|
||||
description
|
||||
"An ordered collection of access control rules.";
|
||||
|
||||
leaf name {
|
||||
type string {
|
||||
length "1..max";
|
||||
}
|
||||
description
|
||||
"Arbitrary name assigned to the rule-list.";
|
||||
}
|
||||
leaf-list group {
|
||||
type union {
|
||||
type matchall-string-type;
|
||||
type group-name-type;
|
||||
}
|
||||
description
|
||||
"List of administrative groups that will be
|
||||
assigned the associated access rights
|
||||
defined by the 'rule' list.
|
||||
The string '*' indicates that all groups apply to the
|
||||
entry.";
|
||||
}
|
||||
|
||||
list rule {
|
||||
key name;
|
||||
ordered-by user;
|
||||
description
|
||||
"One access control rule.
|
||||
Rules are processed in user-defined order until a match is
|
||||
found. A rule matches if 'module-name', 'rule-type', and
|
||||
'access-operations' match the request. If a rule
|
||||
matches, the 'action' leaf determines whether or not
|
||||
access is granted.";
|
||||
|
||||
leaf name {
|
||||
type string {
|
||||
length "1..max";
|
||||
}
|
||||
description
|
||||
"Arbitrary name assigned to the rule.";
|
||||
}
|
||||
|
||||
leaf module-name {
|
||||
type union {
|
||||
type matchall-string-type;
|
||||
type string;
|
||||
}
|
||||
default "*";
|
||||
description
|
||||
"Name of the module associated with this rule.
|
||||
This leaf matches if it has the value '*' or if the
|
||||
object being accessed is defined in the module with the
|
||||
specified module name.";
|
||||
}
|
||||
choice rule-type {
|
||||
description
|
||||
"This choice matches if all leafs present in the rule
|
||||
match the request. If no leafs are present, the
|
||||
choice matches all requests.";
|
||||
case protocol-operation {
|
||||
leaf rpc-name {
|
||||
type union {
|
||||
type matchall-string-type;
|
||||
type string;
|
||||
}
|
||||
description
|
||||
"This leaf matches if it has the value '*' or if
|
||||
its value equals the requested protocol operation
|
||||
name.";
|
||||
}
|
||||
}
|
||||
case notification {
|
||||
leaf notification-name {
|
||||
type union {
|
||||
type matchall-string-type;
|
||||
type string;
|
||||
}
|
||||
description
|
||||
"This leaf matches if it has the value '*' or if its
|
||||
value equals the requested notification name.";
|
||||
}
|
||||
}
|
||||
|
||||
case data-node {
|
||||
leaf path {
|
||||
type node-instance-identifier;
|
||||
mandatory true;
|
||||
description
|
||||
"Data node instance-identifier associated with the
|
||||
data node, action, or notification controlled by
|
||||
this rule.
|
||||
Configuration data or state data
|
||||
instance-identifiers start with a top-level
|
||||
data node. A complete instance-identifier is
|
||||
required for this type of path value.
|
||||
The special value '/' refers to all possible
|
||||
datastore contents.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leaf access-operations {
|
||||
type union {
|
||||
type matchall-string-type;
|
||||
type access-operations-type;
|
||||
}
|
||||
default "*";
|
||||
description
|
||||
"Access operations associated with this rule.
|
||||
This leaf matches if it has the value '*' or if the
|
||||
bit corresponding to the requested operation is set.";
|
||||
}
|
||||
|
||||
leaf action {
|
||||
type action-type;
|
||||
mandatory true;
|
||||
description
|
||||
"The access control action associated with the
|
||||
rule. If a rule has been determined to match a
|
||||
particular request, then this object is used
|
||||
to determine whether to permit or deny the
|
||||
request.";
|
||||
}
|
||||
|
||||
leaf comment {
|
||||
type string;
|
||||
description
|
||||
"A textual description of the access rule.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
module o-ran-file-management {
|
||||
yang-version 1.1;
|
||||
namespace "urn:o-ran:file-management:1.0";
|
||||
prefix "o-ran-file-mgmt";
|
||||
|
||||
import ietf-crypto-types {
|
||||
prefix "ct";
|
||||
}
|
||||
|
||||
|
||||
organization "O-RAN Alliance";
|
||||
|
||||
contact
|
||||
"www.o-ran.org";
|
||||
|
||||
description
|
||||
"This module defines the configuration and operations for handling upload.
|
||||
|
||||
Copyright 2019 the O-RAN Alliance.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the above disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the above disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the Members of the O-RAN Alliance nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.";
|
||||
|
||||
revision "2019-07-03" {
|
||||
description
|
||||
"version 1.1.0
|
||||
|
||||
1) backward compatible changes to correct sFTP Server Authentication .
|
||||
2) minor fixes according to lack of descriptions
|
||||
3) backward compatible changes to introduce groupings";
|
||||
|
||||
reference "ORAN-WG4.M.0-v01.00";
|
||||
}
|
||||
|
||||
revision "2019-02-04" {
|
||||
description
|
||||
"version 1.0.0
|
||||
|
||||
1) imported model from xRAN
|
||||
2) changed namespace and reference from xran to o-ran";
|
||||
|
||||
reference "ORAN-WG4.M.0-v01.00";
|
||||
}
|
||||
|
||||
grouping file-path-grouping {
|
||||
description "Complete logical path of the file to upload/download
|
||||
(no wildcard is allowed) ex : /o-RAN/log/syslog.1";
|
||||
|
||||
leaf local-logical-file-path {
|
||||
type string;
|
||||
mandatory true;
|
||||
description "Local logical file path";
|
||||
}
|
||||
|
||||
leaf remote-file-path {
|
||||
type string;
|
||||
mandatory true;
|
||||
description "URI specifying the remote-file-path on O-DU/NMS.
|
||||
Format:sftp://<username>@<host>[:port]/path";
|
||||
}
|
||||
}
|
||||
|
||||
grouping output-status-grouping {
|
||||
description "Status grouping";
|
||||
|
||||
leaf status {
|
||||
type enumeration {
|
||||
enum SUCCESS {
|
||||
description "";}
|
||||
enum FAILURE {
|
||||
description "";}
|
||||
}
|
||||
description "Operation status";
|
||||
}
|
||||
|
||||
leaf reject-reason {
|
||||
when "../status = 'FAILURE'";
|
||||
type string;
|
||||
description "";
|
||||
}
|
||||
}
|
||||
|
||||
grouping credential-information {
|
||||
description "Type of authentication to use for SFTP upload or download.";
|
||||
choice credentials {
|
||||
case password {
|
||||
container password {
|
||||
presence true;
|
||||
leaf password {
|
||||
type string;
|
||||
mandatory true;
|
||||
description
|
||||
"password needed for O-RU authentication.";
|
||||
}
|
||||
description
|
||||
"password for O-RU authentication method in use";
|
||||
}
|
||||
container server {
|
||||
list keys {
|
||||
key algorithm;
|
||||
ordered-by user;
|
||||
uses ct:public-key-grouping;
|
||||
description
|
||||
"List of allowed algorithms with its keys";
|
||||
}
|
||||
description
|
||||
"Key for sFTP server authentication";
|
||||
}
|
||||
}
|
||||
case certificate {
|
||||
container certificate {
|
||||
presence true;
|
||||
description
|
||||
"certificate authentication method in use";
|
||||
}
|
||||
}
|
||||
description "";
|
||||
}
|
||||
}
|
||||
|
||||
grouping retrieve-input {
|
||||
description "Grouping for information retrieval RPC input";
|
||||
leaf logical-path {
|
||||
type string;
|
||||
mandatory true;
|
||||
description "O-RAN unit of which the files are to be listed.
|
||||
ex : O-RAN/log, o-RAN/PM, O-RAN/transceiver";
|
||||
}
|
||||
leaf file-name-filter {
|
||||
type string;
|
||||
description "Filter which are to be applied on the result list of file names (* is allowed as wild-card).";
|
||||
}
|
||||
}
|
||||
|
||||
grouping retrieve-output {
|
||||
description "Grouping for information retrieval RPC output";
|
||||
uses output-status-grouping;
|
||||
leaf-list file-list {
|
||||
when "../status = 'SUCCESS'";
|
||||
type string;
|
||||
description "List of files in the unit with the filter applied.";
|
||||
}
|
||||
}
|
||||
|
||||
// RPCs
|
||||
|
||||
rpc file-upload {
|
||||
description "File upload over SFTP from equipment to NETCONF client";
|
||||
input {
|
||||
uses file-path-grouping;
|
||||
uses credential-information;
|
||||
}
|
||||
output {
|
||||
uses output-status-grouping;
|
||||
}
|
||||
}
|
||||
|
||||
rpc retrieve-file-list {
|
||||
description "List all the files in the logical O-RAN unit (* is allowed as wild-card).";
|
||||
input {
|
||||
uses retrieve-input;
|
||||
|
||||
}
|
||||
output {
|
||||
uses retrieve-output;
|
||||
}
|
||||
}
|
||||
|
||||
notification file-upload-notification {
|
||||
uses file-path-grouping;
|
||||
uses output-status-grouping;
|
||||
description "";
|
||||
}
|
||||
|
||||
rpc file-download {
|
||||
description
|
||||
"Management plane triggered to generate the download file of O-RU.";
|
||||
input {
|
||||
uses file-path-grouping;
|
||||
uses credential-information;
|
||||
}
|
||||
output {
|
||||
uses output-status-grouping;
|
||||
}
|
||||
}
|
||||
|
||||
notification file-download-event {
|
||||
uses file-path-grouping;
|
||||
uses output-status-grouping;
|
||||
description "";
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user