Commit 1f979696 authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2023_w13' into 'develop'

integration_2023_w13

See merge request oai/openairinterface5g!2037

* !1945 Free RNTI related structures at PHY after UE disconnection
* !2011 Creation of new pipeline LTE-TDD-2x2-container
* !1854 Handle reconfigurationWithSync
* !2019 bugfix: LDPC decoding in the gNB: clear d properly
* !2038 Fix DL 2x2 errors
* !2039 Adding test-case in XML to reset USRP in LTE-TDD pipeline
* !2008 Implement NR-UE Deregistration procedure
* !2023 Rework PDCP OAI API to allow custom SRB data forwarding (e.g., in F1)
* !2015 Update documentation: CI, general README.md, overview of doc README, various improvements
parents 342ea088 06c0979b
......@@ -1895,6 +1895,7 @@ set(libnrnas_emm_msg_OBJS
${NAS_SRC}COMMON/EMM/MSG/FGSUplinkNasTransport.c
${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishRequest.c
${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishmentAccept.c
${NAS_SRC}COMMON/EMM/MSG/FGSDeregistrationRequestUEOriginating.c
)
set(libnrnas_ies_OBJS
......
......@@ -4,8 +4,12 @@
<p align="center">
<a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-OAI--Public--V1.1-blue" alt="License"></a>
<a href="https://releases.ubuntu.com/18.04/"><img src="https://img.shields.io/badge/OS-Ubuntu18-Green" alt="Supported OS"></a>
<a href="https://www.redhat.com/en/enterprise-linux-8"><img src="https://img.shields.io/badge/OS-RHEL8-Green" alt="Supported OS"></a>
<a href="https://releases.ubuntu.com/18.04/"><img src="https://img.shields.io/badge/OS-Ubuntu18-Green" alt="Supported OS Ubuntu 18"></a>
<a href="https://releases.ubuntu.com/20.04/"><img src="https://img.shields.io/badge/OS-Ubuntu20-Green" alt="Supported OS Ubuntu 20"></a>
<a href="https://releases.ubuntu.com/22.04/"><img src="https://img.shields.io/badge/OS-Ubuntu22-Green" alt="Supported OS Ubuntu 22"></a>
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img src="https://img.shields.io/badge/OS-RHEL8-Green" alt="Supported OS RHEL8"></a>
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img src="https://img.shields.io/badge/OS-RHEL9-Green" alt="Supported OS RELH9"></a>
<a href="https://getfedora.org/en/workstation/"><img src="https://img.shields.io/badge/OS-Fedore37-Green" alt="Supported OS Fedora 37"></a>
</p>
<p align="center">
......@@ -13,10 +17,10 @@
</p>
<p align="center">
<a href="https://hub.docker.com/r/rdefosseoai/oai-enb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/rdefosseoai/oai-enb?label=eNB%20docker%20pulls"></a>
<a href="https://hub.docker.com/r/rdefosseoai/oai-lte-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/rdefosseoai/oai-lte-ue?label=LTE-UE%20docker%20pulls"></a>
<a href="https://hub.docker.com/r/rdefosseoai/oai-gnb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/rdefosseoai/oai-gnb?label=gNB%20docker%20pulls"></a>
<a href="https://hub.docker.com/r/rdefosseoai/oai-nr-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/rdefosseoai/oai-nr-ue?label=NR-UE%20docker%20pulls"></a>
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-gnb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-gnb?label=gNB%20docker%20pulls"></a>
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-nr-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-nr-ue?label=NR-UE%20docker%20pulls"></a>
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-enb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-enb?label=eNB%20docker%20pulls"></a>
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-lte-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-lte-ue?label=LTE-UE%20docker%20pulls"></a>
</p>
# OpenAirInterface License #
......@@ -32,12 +36,12 @@ Please see [NOTICE](NOTICE.md) file for third party software that is included in
# Where to Start #
* [General overview of documentation](./doc/README.md)
* [The implemented features](./doc/FEATURE_SET.md)
* [How to build](./doc/BUILD.md)
* [How to run the modems](./doc/RUNMODEM.md)
More information and documentation can be found in the [doc folder](./doc).
Unfortunately, not all information is available there, and information for
Not all information is available in a central place, and information for
specific sub-systems might be available in the corresponding sub-directories.
To find all READMEs, this command might be handy:
......@@ -51,52 +55,20 @@ The OpenAirInterface (OAI) software is composed of the following parts:
```
openairinterface5g
├── charts
├── ci-scripts : Meta-scripts used by the OSA CI process. Contains also configuration files used day-to-day by CI.
├── CMakeLists.txt : Top-level CMakeLists.txt for building
├── cmake_targets : Build utilities to compile (simulation, emulation and real-time platforms), and generated build files.
├── common : Some common OAI utilities, other tools can be found at openair2/UTILS.
├── doc : Contains an up-to-date feature set list and starting tutorials.
├── executables : Top-level executable source files.
├── LICENSE : License file.
├── common : Some common OAI utilities, some other tools can be found at openair2/UTILS.
├── doc : Documentation
├── docker : Dockerfiles to build for Ubuntu and RHEL
├── executables : Top-level executable source files (gNB, eNB, ...)
├── maketags : Script to generate emacs tags.
├── nfapi : Contains the NFAPI code. A local Readme file provides more details.
├── nfapi : (n)FAPI code for MAC-PHY interface
├── openair1 : 3GPP LTE Rel-10/12 PHY layer / 3GPP NR Rel-15 layer. A local Readme file provides more details.
│   ├── PHY
│   ├── SCHED
│   ├── SCHED_NBIOT
│   ├── SCHED_NR
│   ├── SCHED_NR_UE
│   ├── SCHED_UE
│   └── SIMULATION : PHY RF simulation.
├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP + LTE Rel-14 M2AP implementation. Also 3GPP NR Rel-15 RLC/MAC/PDCP/RRC/X2AP.
│   ├── COMMON
│   ├── DOCS
│   ├── ENB_APP
│   ├── F1AP
│   ├── GNB_APP
│   ├── LAYER2/RLC/ : with the following subdirectories: UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0.
│   ├── LAYER2/PDCP/PDCP_v10.1.0
│   ├── M2AP
│   ├── MCE_APP
│   ├── NETWORK_DRIVER
│   ├── NR_PHY_INTERFACE
│   ├── NR_UE_PHY_INTERFACE
│   ├── PHY_INTERFACE
│   ├── RRC
│   ├── UTIL
│   └── X2AP
├── openair3 : 3GPP LTE Rel10 for S1AP, NAS GTPV1-U for both ENB and UE.
│   ├── COMMON
│   ├── DOCS
│   ├── GTPV1-U
│   ├── M3AP
│   ├── MME_APP
│   ├── NAS
│   ├── S1AP
│   ├── SCTP
│   ├── SECU
│   ├── TEST
│   ├── UDP
│   └── UTILS
├── radio : drivers for various radios such as USRP, AW2S, RFsim, ...
└── targets : Top-level wrappers for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW.
├── openshift : OpenShift helm charts for some deployment options of OAI
├── radio : Drivers for various radios such as USRP, AW2S, RFsim, ...
└── targets : Some configuration files; only historical relevance, and might be deleted in the future
```
......@@ -385,6 +385,27 @@ pipeline {
}
}
}
stage ("LTE-TDD-2x2-Container") {
when { expression {do4Gtest} }
steps {
script {
triggerSlaveJob ('RAN-LTE-TDD-2x2-Container', 'LTE-TDD-2x2-Container')
}
}
post {
always {
script {
finalizeSlaveJob('RAN-LTE-TDD-2x2-Container')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
//avra is offline, re-enable once it is available
//stage ("T1-Offload-Test") {
// when { expression {do5Gtest} }
......
......@@ -844,7 +844,7 @@ class Containerize():
CreateWorkspace(mySSH, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5)
mySSH.command('cp docker-compose.yml ci-docker-compose.yml', '\$', 5)
mySSH.command('cp docker-compose.y*ml ci-docker-compose.yml', '\$', 5)
imagesList = ['oai-enb', 'oai-gnb', 'oai-nr-cuup']
for image in imagesList:
imageToUse = self.ImageTagToUse(image)
......@@ -1559,17 +1559,6 @@ class Containerize():
mySSH.close()
if svrName == 'nepes':
mySSH.open(ipAddr, userName, password)
# Check if route to porcepix epc exists: not necessary, is on same host
#mySSH.command('ip route | grep --colour=never "192.168.61.192/26"', '\$', 10)
#result = re.search('172.21.16.136', mySSH.getBefore())
#if result is None:
# mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.61.192/26 via 172.21.16.136 dev enp0s31f6', '\$', 10)
# Check if X2 route to obelix enb exists: not necessary, gnb is on ofqot
#mySSH.command('ip route | grep --colour=never "192.168.68.128/26"', '\$', 10)
#result = re.search('172.21.16.128', mySSH.getBefore())
#if result is None:
# mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.128/26 via 172.21.16.128 dev enp0s31f6', '\$', 10)
# Check if forwarding is enabled
# Check if route to ofqot gnb exists
mySSH.command('ip route | grep --colour=never "192.168.68.192/26"', '\$', 10)
result = re.search('172.21.16.109', mySSH.getBefore())
......
......@@ -1227,7 +1227,7 @@ class OaiCiTest():
raise Exception("could not corver prod-trf-gen IP address")
cn_target_ip = result.group('trf_ip_addr')
SSH.close()
cn_iperf_prefix = "docker exec -it prod-trf-gen" # -w /iperf-2.0.13 necessary?
cn_iperf_prefix = "docker exec prod-trf-gen" # -w /iperf-2.0.13 necessary?
else: # ltebox, sabox
cn_target_ip = "192.172.0.1"
cn_iperf_prefix = ""
......
......@@ -172,7 +172,7 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR";
mme_ip_address = ( { ipv4 = "192.168.61.195";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
......@@ -191,11 +191,11 @@ eNBs =
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eno1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
ENB_IPV4_ADDRESS_FOR_S1_MME = "172.21.16.128";
ENB_INTERFACE_NAME_FOR_S1U = "eno1";
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
ENB_IPV4_ADDRESS_FOR_S1U = "172.21.16.128";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
ENB_IPV4_ADDRESS_FOR_X2C = "172.21.16.128";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
......
......@@ -172,7 +172,7 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR";
mme_ip_address = ( { ipv4 = "192.168.61.195";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
......@@ -191,11 +191,11 @@ eNBs =
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eno1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
ENB_IPV4_ADDRESS_FOR_S1_MME = "172.21.16.128";
ENB_INTERFACE_NAME_FOR_S1U = "eno1";
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
ENB_IPV4_ADDRESS_FOR_S1U = "172.21.16.128";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
ENB_IPV4_ADDRESS_FOR_X2C = "172.21.16.128";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
......
......@@ -27,6 +27,7 @@ Replaces xml_files/enb_usrp210_band40_test_05mhz_tm1.xml
<htmlTabName>Test-TDD-05MHz-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
300000
100000
111110
040101
......@@ -57,6 +58,13 @@ Replaces xml_files/enb_usrp210_band40_test_05mhz_tm1.xml
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="300000">
<class>Custom_Command</class>
<desc>Reset USRP</desc>
<node>starsky</node>
<command>sudo -S b2xx_fx3_utils --reset-device</command>
</testCase>
<testCase id="030104">
<class>Deploy_Object</class>
<desc>Deploy eNB (TDD/Band40/5MHz/B200) in a container</desc>
......
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-LTE-2x2-N3XX-TM1</htmlTabRef>
<htmlTabName>2.6 Ghz TDD LTE 2x2 TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
111111
100000
010000
030101
010001
000001
050000
050001
070000
070001
010010
010002
030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<test_svr_id>0</test_svr_id>
<images_to_pull>oai-enb</images_to_pull>
</testCase>
<testCase id="100000">
<class>Custom_Command</class>
<desc>Disable Sleep States</desc>
<node>obelix</node>
<command>sudo cpupower idle-set -D 0</command>
</testCase>
<testCase id="200000">
<class>Custom_Command</class>
<desc>Enable Sleep States</desc>
<node>obelix</node>
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="030101">
<class>Deploy_Object</class>
<desc>Deploy eNB (TDD/Band38/2.6Ghz/N3XX) in a container</desc>
<yaml_path>ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010001">
<class>Attach_UE</class>
<desc>Attach UE</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20 pings</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100 pings, size 1024</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 26M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 7M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="010010">
<class>Detach_UE</class>
<desc>Detach UE</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="030201">
<class>Undeploy_Object</class>
<desc>Undeploy gNB</desc>
<yaml_path>ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<!-- <d_retx_th>1,100,100,100</d_retx_th>
<u_retx_th>1,100,100,100</u_retx_th>
?
-->
</testCase>
</testCaseList>
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-LTE-2x2-N3XXi-TM2</htmlTabRef>
<htmlTabName>2.6 Ghz TDD LTE 2x2 TM2</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
111111
100000
010000
030101
010001
000001
050000
050001
070000
070001
010010
010002
030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<test_svr_id>0</test_svr_id>
<images_to_pull>oai-enb</images_to_pull>
</testCase>
<testCase id="100000">
<class>Custom_Command</class>
<desc>Disable Sleep States</desc>
<node>obelix</node>
<command>sudo cpupower idle-set -D 0</command>
</testCase>
<testCase id="200000">
<class>Custom_Command</class>
<desc>Enable Sleep States</desc>
<node>obelix</node>
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="030101">
<class>Deploy_Object</class>
<desc>Deploy eNB (TDD/Band38/2.6Ghz/N3XX) in a container</desc>
<yaml_path>ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010001">
<class>Attach_UE</class>
<desc>Attach UE</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20 pings</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100 pings, size 1024</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 1M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 7M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="010010">
<class>Detach_UE</class>
<desc>Detach UE</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="030201">
<class>Undeploy_Object</class>
<desc>Undeploy gNB</desc>
<yaml_path>ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<!-- <d_retx_th>1,100,100,100</d_retx_th>
<u_retx_th>1,100,100,100</u_retx_th>
?
-->
</testCase>
</testCaseList>
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-LTE-TM1-Tab1</htmlTabRef>
<htmlTabName>LTE 2x2 TM1 Ping DL UL with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
100000
010000
030000
010001
050000
050001
070000
070001
010011
010002
080000
200000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100000">
<class>Custom_Command</class>
<desc>Disable Sleep States</desc>
<node>obelix</node>
<command>sudo cpupower idle-set -D 0</command>
</testCase>
<testCase id="200000">
<class>Custom_Command</class>
<desc>Enable Sleep States</desc>
<node>obelix</node>
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010001">
<class>Attach_UE</class>
<desc>Attach Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010011">
<class>Detach_UE</class>
<desc>Detach Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="030000">
<class>Initialize_eNB</class>
<desc>Initialize eNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
<eNB_Trace>yes</eNB_Trace>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>172.21.19.13</USRP_IPAddress>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20 pings</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100 pings, size 1024</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 26M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 7M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="080000">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
</testCase>
<testCase id="080001">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
</testCase>
</testCaseList>
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-LTE-TM2-Tab2</htmlTabRef>
<htmlTabName>LTE 2x2 TM2 Ping DL UL with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
100000
010000
030001
010001
050002
050003
070002
070003
010011
010002
080000
200000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100000">
<class>Custom_Command</class>
<desc>Disable Sleep States</desc>
<node>obelix</node>
<command>sudo cpupower idle-set -D 0</command>
</testCase>
<testCase id="200000">
<class>Custom_Command</class>
<desc>Enable Sleep States</desc>
<node>obelix</node>
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010001">
<class>Attach_UE</class>
<desc>Attach Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="010011">
<class>Detach_UE</class>
<desc>Detach Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="030001">
<class>Initialize_eNB</class>
<desc>Initialize eNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.lte_2x2_tm2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
<eNB_Trace>yes</eNB_Trace>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>172.21.19.13</USRP_IPAddress>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
<testCase id="050002">
<class>Ping</class>
<desc>Ping: 20 pings</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="050003">
<class>Ping</class>
<desc>Ping: 100 pings, size 1024</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="070002">
<class>Iperf</class>
<desc>iperf (DL/1Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 1M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070003">
<class>Iperf</class>
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 7M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="080000">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
</testCase>
<testCase id="080001">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
</testCase>
</testCaseList>
......@@ -219,7 +219,7 @@ services:
F1_DU_IP_ADDRESS: 192.168.71.142
F1_CU_D_PORT: 2153
F1_DU_D_PORT: 2153
USE_ADDITIONAL_OPTIONS: --sa --rfsim --rfsimulator.wait_timeout 20 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
depends_on:
- oai-cu
networks:
......
......@@ -180,7 +180,7 @@ services:
GNB_NGA_IP_ADDRESS: 192.168.71.140
GNB_NGU_IF_NAME: eth0
GNB_NGU_IP_ADDRESS: 192.168.71.140
USE_ADDITIONAL_OPTIONS: --sa -E --rfsim --rfsimulator.wait_timeout 20 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --sa -E --rfsim --log_config.global_log_options level,nocolor,time
depends_on:
- oai-ext-dn
networks:
......
......@@ -181,7 +181,7 @@ services:
GNB_NGU_IF_NAME: eth0
GNB_NGU_IP_ADDRESS: 192.168.71.140
SDR_ADDRS: serial=XXXXXXX
USE_ADDITIONAL_OPTIONS: --sa -E --rfsim --rfsimulator.wait_timeout 20 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --sa -E --rfsim --log_config.global_log_options level,nocolor,time
depends_on:
- oai-ext-dn
networks:
......
......@@ -169,7 +169,7 @@ services:
environment:
RFSIMULATOR: server
USE_VOLUMED_CONF: 'yes'
USE_ADDITIONAL_OPTIONS: --sa --rfsim --rfsimulator.wait_timeout 20 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
depends_on:
- oai-ext-dn
networks:
......
......@@ -169,7 +169,7 @@ services:
environment:
RFSIMULATOR: server
USE_VOLUMED_CONF: 'yes'
USE_ADDITIONAL_OPTIONS: --sa --rfsim --rfsimulator.wait_timeout 20 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
depends_on:
- oai-ext-dn
networks:
......
......@@ -216,7 +216,7 @@ services:
environment:
RFSIMULATOR: server
USE_VOLUMED_CONF: 'yes'
USE_ADDITIONAL_OPTIONS: --sa --rfsim --rfsimulator.wait_timeout 20 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
networks:
ran_net:
ipv4_address: 192.168.72.142
......
......@@ -169,7 +169,7 @@ services:
environment:
RFSIMULATOR: server
USE_VOLUMED_CONF: 'yes'
USE_ADDITIONAL_OPTIONS: --sa --rfsim --rfsimulator.wait_timeout 20 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
depends_on:
- oai-ext-dn
networks:
......
version: '3.8'
services:
oai-enb:
image: oai-enb:latest
privileged: true
container_name: oai-enb
environment:
TZ: Europe/Paris
USE_VOLUMED_CONF: 'yes'
USE_ADDITIONAL_OPTIONS: --usrp-tx-thread-config 1 --thread-pool 0,2,4,6
volumes:
- ../../conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf:/opt/oai-enb/etc/mounted.conf
network_mode: "host"
healthcheck:
test: /bin/bash -c "pgrep lte-softmodem"
interval: 10s
timeout: 5s
retries: 5
version: '3.8'
services:
oai-enb:
image: oai-enb:latest
privileged: true
container_name: oai-enb
environment:
TZ: Europe/Paris
USE_VOLUMED_CONF: 'yes'
USE_ADDITIONAL_OPTIONS: --usrp-tx-thread-config 1 --thread-pool 0,2,4,6
volumes:
- ../../conf_files/enb.band38.lte_2x2_tm2.100PRB.usrpn310.conf:/opt/oai-enb/etc/mounted.conf
network_mode: "host"
healthcheck:
test: /bin/bash -c "pgrep lte-softmodem"
interval: 10s
timeout: 5s
retries: 5
......@@ -10,10 +10,9 @@
# define NUMBER_OF_ULSCH_MAX 8
# define NUMBER_OF_DLSCH_MAX 8
# define NUMBER_OF_SRS_MAX 16
# define NUMBER_OF_NR_ULSCH_MAX MAX_MOBILES_PER_GNB
# define NUMBER_OF_NR_DLSCH_MAX MAX_MOBILES_PER_GNB
# define NUMBER_OF_SCH_STATS_MAX 16
# define NUMBER_OF_NR_SCH_STATS_MAX MAX_MOBILES_PER_GNB
#define NUMBER_FRAMES_PHY_UE_INACTIVE 10
#define MAX_MANAGED_ENB_PER_MOBILE 2
#define MAX_MANAGED_GNB_PER_MOBILE 2
......
......@@ -24,6 +24,7 @@
#include <vector>
#include <map>
#include <sys/eventfd.h>
#include <semaphore.h>
extern "C" {
......@@ -434,24 +435,32 @@ extern "C" {
void itti_send_terminate_message(task_id_t task_id) {
}
pthread_mutex_t signal_mutex;
sem_t itti_sem_block;
void itti_wait_tasks_unblock()
{
int rc = sem_post(&itti_sem_block);
AssertFatal(rc == 0, "error in sem_post(): %d %s\n", errno, strerror(errno));
}
static void catch_sigterm(int) {
static const char msg[] = "\n** Caught SIGTERM, shutting down\n";
__attribute__((unused))
int unused = write(STDOUT_FILENO, msg, sizeof(msg) - 1);
pthread_mutex_unlock(&signal_mutex);
itti_wait_tasks_unblock();
}
void itti_wait_tasks_end(void) {
pthread_mutex_init(&signal_mutex, NULL);
pthread_mutex_lock(&signal_mutex);
void itti_wait_tasks_end(void (*handler)(int))
{
int rc = sem_init(&itti_sem_block, 0, 0);
AssertFatal(rc == 0, "error in sem_init(): %d %s\n", errno, strerror(errno));
signal(SIGTERM, catch_sigterm);
signal(SIGINT, catch_sigterm);
if (handler == NULL) /* no handler given: install default */
handler = catch_sigterm;
signal(SIGTERM, handler);
signal(SIGINT, handler);
pthread_mutex_lock(&signal_mutex);
rc = sem_wait(&itti_sem_block);
AssertFatal(rc == 0, "error in sem_wait(): %d %s\n", errno, strerror(errno));
}
void itti_update_lte_time(uint32_t frame, uint8_t slot) {}
......
......@@ -550,10 +550,13 @@ MessageDef *itti_alloc_new_message_sized(
MessagesIds message_id,
MessageHeaderSize size);
/** \brief handle signals and wait for all threads to join when the process complete.
This function should be called from the main thread after having created all ITTI tasks.
/** \brief Wait for SIGINT/SIGTERM signals to unblock ITTI.
This function should be called from the main thread after having created all ITTI tasks. If handler is NULL, a default handler is installed.
\param handler a custom signal handler. To unblock, it should call itti_wait_tasks_unblock()
**/
void itti_wait_tasks_end(void);
void itti_wait_tasks_end(void (*handler)(int));
/** \brif unblocks ITTI waiting in itti_wait_tasks_end(). **/
void itti_wait_tasks_unblock(void);
void itti_set_task_real_time(task_id_t task_id);
/** \brief Send a termination message to all tasks.
......
This diff is collapsed.
......@@ -1340,6 +1340,7 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_UE/mac_extern.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h \
......
......@@ -25,7 +25,7 @@ git config --global user.email "Your email address"
## In order to clone the Git repository (for OAI Users without login to gitlab server)
Cloning RAN repository (eNB RAN + UE RAN):
Cloning RAN repository:
```shell
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
......@@ -35,22 +35,18 @@ git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
Please send email to [contact@openairinterface.org](mailto:contact@openairinterface.org) to be added to the repository
as a developer (only important for users who want to commit code to the repository). If
you do not have account on gitlab.eurecom.fr, please register yourself to gitlab.eurecom.fr and provide the identifiant in the email.
you do not have account on gitlab.eurecom.fr, please register yourself to gitlab.eurecom.fr and provide the login name in the email.
# Which branch to checkout?
On the RAN side:
* **master**: This branch is targeted for the user community. Since January 2019, it is also subject to a Continuous Integration process. The update frequency is about once every 2-3 months. We are also performing bug fixes on this branch.
* **develop**: This branch contains recent commits that are tested on our CI test bench. The update frequency is about once a week.
More information can be found in [a separate page](../CONTRIBUTING.md).
Please see the work flow and policies page:
# Which branch to checkout?
https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/oai-policies-home
`develop`: contains recent commits that are tested on our CI test bench. The update frequency is about once a week. 5G is only in this branch. It is the recommended and default branch.
`master`: contains a stable version of 4G, and will be updated in the future with 5G.
you can find the latest stable tag release here:
Please see the work flow and policies page: https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/oai-policies-home
https://gitlab.eurecom.fr/oai/openairinterface5g/tags
You can find the latest stable tag release here: https://gitlab.eurecom.fr/oai/openairinterface5g/tags
The tag naming conventions are:
......@@ -60,4 +56,3 @@ The tag naming conventions are:
- On `develop` branch **`yyyy`.w`xx`**
* `yyyy` is the calendar year
* `xx` the week number within the year
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OpenAirInterface documentation overview</font></b>
</td>
</tr>
</table>
[[_TOC_]]
# General
- [FEATURE_SET.md](./FEATURE_SET.md): lists supported features
- [GET_SOURCES.md](./GET_SOURCES.md): how to download the sources
- [BUILD.md](./BUILD.md): how to build the sources
- [clang-format.md](./clang-format.md): how to format the code
There is some general information in the [OpenAirInterface Gitlab Wiki](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/home)
# Tutorials
- Step-by-step tutorials to set up 5G:
* [OAI 5GC](./NR_SA_Tutorial_OAI_CN5G.md)
* [OAI gNB with COTS UE](./NR_SA_Tutorial_COTS_UE.md)
* [OAI NR-UE](./NR_SA_Tutorial_OAI_nrUE.md)
- [RUNMODEM.md](./RUNMODEM.md): Generic information on how to
* Run simulators
* Run with hardware
* Specific OAI modes (phy-test, do-ra, noS1)
* (5G) Using SDAP and custom DRBs
* IF setups and arbitrary frequencies
* MIMO
- [How to run a 5G-SA setup](./TESTING_5GSA_setup.md)
- [How to run a 5G-NSA setup](./TESTING_GNB_W_COTS_UE.md)
- [How to run a 4G setup using L1 simulator](./L1SIM.md) _Note: we recommend the RFsimulator_
- [How to use the L2 simulator](./L2NFAPI.md)
- [How to use multiple BWPs](./RUN_NR_multiple_BWPs.md)
- [How to run OAI-VNF and OAI-PNF](./RUN_NR_NFAPI.md) _Note: does not work currently_
- [How to use the positioning reference signal (PRS)](./RUN_NR_PRS.md)
- [How to use device-to-device communication (D2D, 4G)](./d2d_emulator_setup.txt)
Legacy unmaintained files:
- `L2NFAPI_NOS1.md`, `L2NFAPI_S1.md`: old L2simulator, not valid anymore
- `SystemX-tutorial-design.md`
- `UL_MIMO.txt`
# Designs
- General software architecture notes: [SW_archi.md](./SW_archi.md)
- [Information on E1](./E1-design.md)
- [Information on F1](./F1-design.md)
- [Information on how NR nFAPI works](./NR_NFAPI_archi.md)
- [Flow graph of the L1 in gNB](SW-archi-graph.md)
- [L1 threads in NR-UE](./nr-ue-design.md)
Legacy unmaintained files:
- 5Gnas.md
# Building and running from images
- [How to build images](../docker/README.md)
- [How to run 5G with the RFsimulator from images](../ci-scripts/yaml_files/5g_rfsimulator/README.md)
- [How to run 4G with the RFsimulator from images](../ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/README.md)
- [How to run 5G with the L2simulator from images](../ci-scripts/yaml_files/5g_l2sim_tdd/README.md)
- [How to run images in OpenShift](../openshift/README.md)
# Libraries
## General
- The [T tracer](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/T/): a generic tracing tool (VCD, Wireshark, GUI, to save for later, ...)
- [OPT](../openair2/UTIL/OPT/README.txt): how to trace to wireshark
- The [configuration module](../common/config/DOC/config.md)
- The [logging module](../common/utils/LOG/DOC/log.md)
- The [shared object loader](../common/utils/DOC/loader.md)
- The [threadpool](../common/utils/threadPool/thread-pool.md) used in L1
## SDRs
Some directories under `radio` contain READMEs:
- [RFsimulator](../radio/rfsimulator/README.md)
- [USRP](../radio/USRP/README.md)
- [BladeRF](../radio/BLADERF/README)
- [IQPlayer](../radio/iqplayer/DOC/iqrecordplayer_usage.md)
The other SDRs (AW2S, LimeSDR, ...) have no READMEs.
## Special-purpose libraries
- OAI comes with an integrated [telnet server](../common/utils/telnetsrv/DOC/telnethelp.md) to monitor and control
- OAI comes with an integrated [web server](../common/utils/websrv/DOC/websrv.md)
# CI
- [TESTBenches.md](./TESTBenches.md) lists the CI setup and links to pipelines
This diff is collapsed.
......@@ -327,25 +327,23 @@ successful_delivery() and max_retx_reached(): in ??? trigger, the RLC sends a it
The PDCP implementation is also protected through a general mutex.
The design is very similar to rlc layer. The pdcp data is isolated and encapsulated.
pdcp_layer_init(): same as rlc init
nr_pdcp_layer_init(): same as rlc init
we have to call a second init function: pdcp_module_init()
At Tx side (DL in gNB), pdcp_data_req() is the entry function that the upper layer calls.
At Tx side (DL in gNB), `pdcp_data_req_drb()` and `pdcp_data_req_srb()` are the entry functions that the upper layer calls.
The upper layer can be GTP or a PDCP internal thread enb_tun_read_thread() that read directly from Linux socket in case we skip 3GPP core implementation.
PDCP internals for pdcp_data_req() is thread safe: inside pdcp_data_req_drb(), the pdcp manager protects with the mutex the access to the SDU receiving function of PDCP (recv_sdu() callback, corresponding to nr_pdcp_entity_drb_am_recv_sdu() for DRBs). When it needs, the pdcp layer push this data to rlc by calling : rlc_data_req()
Also, incoming downlink sdu can comme from internal RRC: in this case, pdcp_run() reads a itti queue, for message RRC_DCCH_DATA_REQ, to0 only call 'pdcp_data_req()'
PDCP internals for nr_pdcp_data_req_srb()/nr_pdcp_data_req_drb() are thread safe: inside them, the pdcp manager protects with the mutex the access to the SDU receiving function of PDCP (recv_sdu() callback, corresponding to nr_pdcp_entity_drb_am_recv_sdu() for DRBs). When it needs, the pdcp layer push this data to rlc by calling : rlc_data_req()
At Rx side, pdcp_data_ind() is the entry point that receives the data from RLC.
- Inside pdcp_data_ind(), the pdcp manager mutex protects the access to the PDU receiving function of PDCP (recv_pdu() callback corresponding to nr_pdcp_entity_drb_am_recv_pdu() for DRBs)
- Then deliver_sdu_drb() function sends the received data to GTP thread through an ITTI message (GTPV1U_TUNNEL_DATA_REQ).
pdcp_config_set_security(): not yet developped
nr_pdcp_config_set_security(): sets the keys for AS security of a UE
nr_DRB_preconfiguration(): the mac layer calls this for ???
nr_DRB_preconfiguration(): the mac layer calls this for configuration in phy-test/do-ra mode
nr_pdcp_add_srbs() adds UE SRBs in pdcp, pdcp_remove_UE() removes it
nr_pdcp_add_drbs() adds UE DRBs in pdcp, pdcp_remove_UE() removes it
nr_pdcp_add_srbs() adds UE SRBs in pdcp, nr_pdcp_remove_UE() removes it
nr_pdcp_add_drbs() adds UE DRBs in pdcp, nr_pdcp_remove_UE() removes it
# GTP
Gtp + UDP are two twin threads performing the data plane interface to the core network
......@@ -357,7 +355,7 @@ PDCP layer push to the GTP queue (outside UDP thread that do almost nothing and
## GTP thread running code from other layers
gtp thread calls directly pdcp_data_req(), so it runs inside it's context internal pdcp structures updates
gtp thread calls directly nr_pdcp_data_req_drb(), so it runs inside it's context internal pdcp structures updates
## inside other threads
gtpv1u_create_s1u_tunnel(), delete tunnel, ... functions are called inside the other threads, without mutex.
......
This diff is collapsed.
......@@ -395,18 +395,3 @@ The following parts have been validated with FR1 COTS UE:
DL traffic : 3Mbps
UL traffic : 1Mbps
some packet losses might still occur even in ideal channel conditions
## CI integration
The automation scripts are available on ILIADE.
The end-to-end test is integrated in the CI flow in a semi-automated manner, comprising 3 steps:
- update a YAML file comprising the IT resources definition, branch and commit number the test has to run on
- run the python script that generates the test from the YAML file
```
python3 obj_build_from_yaml.py py_params_template.yaml fr1.sh
```
- run the test (fr1.sh)
At the date of writing, the test comprises the deployment of the components (epc, eNB, gNB, cots ue) and the execution of 2 pings procedures (20 pings in 20sec, then 5 pings in 1sec)
This automation is run for every integration branch to be merged into develop.
......@@ -15,27 +15,24 @@
\node[faraday, label={[anchor=south east]above right:Faraday cage}] (faraday) {};
\node[above left=0cm and 2.8cm of faraday, label=above:obelix] (obelix)
\node[above left=-0.50cm and 2.8cm of faraday, label=above:nepes] (nepes)
{\includegraphics[width=1.2cm]{server}};
\node[right=0.3cm of obelix, label=above:B200-mini] (b210o)
{\includegraphics[width=1.2cm]{b200-mini}} edge (obelix);
\node[right=0.3cm of nepes, label=above:B200-mini] (b210o)
{\includegraphics[width=1.2cm]{b200-mini}} edge (nepes);
\node[below right=0.35cm of faraday.north west] (anto)
{\includegraphics[width=0.3cm]{antenna}};
\draw (b210o) -| node [pos=0.2, duplexer] {B7} (anto);
\node[below left=0cm and 2.8cm of faraday, label=above:nepes] (nepes)
\node[below left=-0.50cm and 2.8cm of faraday, label=below:ofqot] (ofqot)
{\includegraphics[width=1.2cm]{server}};
\node[right=0.3cm of nepes, label=above:B200-mini] (b210n)
{\includegraphics[width=1.2cm]{b200-mini}} edge (nepes);
\draw (obelix) -- (b210o);
\node[right=0.3cm of ofqot, label=above:B200-mini] (b210n)
{\includegraphics[width=1.2cm]{b200-mini}} edge (ofqot);
\draw (nepes) -- (b210o);
\node[above right=0.35cm of faraday.south west] (antn)
{\includegraphics[width=0.3cm]{antenna}};
\draw (b210n) -| node [pos=0.2, duplexer] {n78} (antn);
\node[left=5cm of faraday, label=above:porcepix] (porcepix)
{\includegraphics[width=1.2cm]{server}};
\draw (obelix) -- (porcepix);
\draw (nepes) -- (porcepix);
\draw (nepes) -- (ofqot);
\node[right=1.5cm of faraday, label=above:RM500Q-GL] (quectel)
{\includegraphics[height=1.2cm]{quectel}};
......
......@@ -16,7 +16,7 @@
\node[label=above:porcepix] (porcepix)
{\includegraphics[width=1.2cm]{server}};
\node[above right=1cm and 2cm of porcepix, label=above:asterix] (asterix)
\node[above right=-0.4cm and 2cm of porcepix, label=above:asterix] (asterix)
{\includegraphics[width=1.2cm]{server}}
edge (porcepix);
\node[right=0.3cm of asterix, label=above:N310] (n310a)
......@@ -27,7 +27,7 @@
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[right=2cm of porcepix, label=above:obelix] (obelix)
\node[below right=-0.4cm and 2cm of porcepix, label=above:obelix] (obelix)
{\includegraphics[width=1.2cm]{server}}
edge (porcepix);
\node[above right=-0.5cm and 0.3cm of obelix, label=above:N310] (n310o)
......@@ -45,7 +45,7 @@
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=-1.3cm and 5.0cm of n310a.east, label=above:RM500Q-GL] (quectel)
\node[above right=-0.5cm and 5.0cm of n310o.east, label=above:RM500Q-GL] (quectel)
{\includegraphics[height=1.2cm]{quectel}};
\node[above left=-0.1cm and 0.8cm of quectel.west] (aq2)
{\includegraphics[width=0.3cm]{antenna}} edge (quectel);
......@@ -59,10 +59,5 @@
{\includegraphics[width=1.2cm]{server}}
edge (quectel);
\node[above right=-0.3cm and 5.0cm of x310o.east, label=above:amariue] (amariue)
{\includegraphics[height=1.2cm]{server}};
\node[left=0.8cm of amariue.west] (aa1)
{\includegraphics[width=0.3cm]{antenna}} edge (amariue);
\end{tikzpicture}
\end{document}
......@@ -181,6 +181,21 @@ bool sdap_data_req(protocol_ctxt_t *ctxt_p,
abort();
}
/* hack: gtp_itf.cpp requires this empty function to be defined here */
bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const mui_t muiP,
const confirm_t confirmP,
const sdu_size_t sdu_buffer_size,
unsigned char *const sdu_buffer,
const pdcp_transmission_mode_t mode,
const uint32_t *const sourceL2Id,
const uint32_t *const destinationL2Id)
{
abort();
}
/* forward declarations */
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
......@@ -614,7 +629,7 @@ int main ( int argc, char **argv )
//getchar();
if(IS_SOFTMODEM_DOSCOPE)
load_softscope("enb",NULL);
itti_wait_tasks_end();
itti_wait_tasks_end(NULL);
#if USING_GPROF
// Save the gprof data now (rather than via atexit) in case we crash while shutting down
......
......@@ -699,7 +699,7 @@ int main( int argc, char **argv ) {
printf("TYPE <CTRL-C> TO TERMINATE\n");
//getchar();
printf("Entering ITTI signals handler\n");
itti_wait_tasks_end();
itti_wait_tasks_end(NULL);
printf("Returned from ITTI signal handler\n");
oai_exit=1;
printf("oai_exit=%d\n",oai_exit);
......
......@@ -28,7 +28,7 @@
#include "nfapi/oai_integration/vendor_ext.h"
#include "openair2/F1AP/f1ap_common.h"
#include "openair2/GNB_APP/gnb_config.h"
#include "pdcp.h"
#include "nr_pdcp/nr_pdcp_oai_api.h"
RAN_CONTEXT_t RC;
THREAD_STRUCT thread_struct;
......@@ -147,13 +147,13 @@ int main(int argc, char **argv)
AssertFatal(rc >= 0, "Create task for GTPV1U failed\n");
rc = itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL);
AssertFatal(rc >= 0, "Create task for CUUP E1 failed\n");
pdcp_layer_init();
nr_pdcp_layer_init();
MessageDef *msg = RCconfig_NR_CU_E1(true);
AssertFatal(msg != NULL, "Send init to task for E1AP UP failed\n");
itti_send_msg_to_task(TASK_CUUP_E1, 0, msg);
printf("TYPE <CTRL-C> TO TERMINATE\n");
itti_wait_tasks_end();
itti_wait_tasks_end(NULL);
logClean();
printf("Bye.\n");
......
......@@ -128,7 +128,8 @@ void tx_func(void *param) {
}
void rx_func(void *param) {
void rx_func(void *param)
{
processingData_L1_t *info = (processingData_L1_t *) param;
PHY_VARS_gNB *gNB = info->gNB;
int frame_rx = info->frame_rx;
......@@ -173,46 +174,11 @@ void rx_func(void *param) {
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
/* hack to remove UEs */
extern int rnti_to_remove[10];
extern volatile int rnti_to_remove_count;
extern pthread_mutex_t rnti_to_remove_mutex;
if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
int up_removed = 0;
int down_removed = 0;
int pucch_removed = 0;
for (int i = 0; i < rnti_to_remove_count; i++) {
LOG_W(NR_PHY, "to remove rnti 0x%04x\n", rnti_to_remove[i]);
void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
int j;
for (j = 0; j < NUMBER_OF_NR_ULSCH_MAX; j++)
if (gNB->ulsch[j]->rnti == rnti_to_remove[i]) {
gNB->ulsch[j]->rnti = 0;
gNB->ulsch[j]->harq_mask = 0;
int h;
for (h = 0; h < NR_MAX_ULSCH_HARQ_PROCESSES; h++) {
gNB->ulsch[j]->harq_processes[h]->status = NR_SCH_IDLE;
gNB->ulsch[j]->harq_processes[h]->round = 0;
gNB->ulsch[j]->harq_processes[h]->handled = 0;
}
up_removed++;
}
for (j = 0; j < gNB->max_nb_pucch; j++)
if (gNB->pucch[j]->active > 0 &&
gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) {
gNB->pucch[j]->active = 0;
gNB->pucch[j]->pucch_pdu.rnti = 0;
pucch_removed++;
}
}
if (rnti_to_remove_count) LOG_W(NR_PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed);
rnti_to_remove_count = 0;
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
reset_active_stats(gNB, frame_tx);
reset_active_ulsch(gNB, frame_tx);
// RX processing
int rx_slot_type = nr_slot_select(cfg,frame_rx,slot_rx);
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) {
// UE-specific RX processing for subframe n
// TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
......
......@@ -59,7 +59,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "pdcp.h"
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
#include "intertask_interface.h"
......@@ -176,6 +176,12 @@ openair0_config_t openair0_cfg[MAX_CARDS];
double cpuf;
/* hack: pdcp_run() is required by 4G scheduler which is compiled into
* nr-softmodem because of linker issues */
void pdcp_run(const protocol_ctxt_t *const ctxt_pP)
{
abort();
}
/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
* this is very hackish - find a proper solution
......@@ -556,13 +562,8 @@ void init_pdcp(void) {
PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT:
LINK_ENB_PDCP_TO_GTPV1U_BIT;
if (!get_softmodem_params()->nsa) {
if (!NODE_IS_DU(get_node_type())) {
pdcp_layer_init();
nr_pdcp_module_init(pdcp_initmask, 0);
}
} else {
pdcp_layer_init();
if (!NODE_IS_DU(get_node_type())) {
nr_pdcp_layer_init();
nr_pdcp_module_init(pdcp_initmask, 0);
}
}
......@@ -733,7 +734,7 @@ int main( int argc, char **argv ) {
// wait for end of program
printf("Entering ITTI signals handler\n");
printf("TYPE <CTRL-C> TO TERMINATE\n");
itti_wait_tasks_end();
itti_wait_tasks_end(NULL);
printf("Returned from ITTI signal handler\n");
oai_exit=1;
printf("oai_exit=%d\n",oai_exit);
......
......@@ -33,7 +33,7 @@
#include "executables/softmodem-common.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "radio/COMMON/common_lib.h"
#include "pdcp.h"
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
/*
* NR SLOT PROCESSING SEQUENCE
......@@ -157,6 +157,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
ue->mac_enabled = 1;
ue->if_inst = nr_ue_if_module_init(0);
ue->dci_thres = 0;
ue->target_Nid_cell = -1;
// initialize all signal buffers
init_nr_ue_signal(ue, nb_connected_gNB);
......@@ -355,12 +356,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
nr_ue_ul_scheduler(&ul_info);
nr_ue_pucch_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, NULL);
}
if (!IS_SOFTMODEM_NOS1 && get_softmodem_params()->sa) {
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, mac->crnti, frame, slot, 0);
pdcp_run(&ctxt);
}
process_queued_nr_nfapi_msgs(mac, sfn_slot);
}
return NULL;
......@@ -413,7 +408,11 @@ static void UE_synch(void *arg) {
*/
}
LOG_W(PHY, "Starting sync detection\n");
if (UE->target_Nid_cell != -1) {
LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell);
} else {
LOG_W(NR_PHY, "Starting sync detection\n");
}
switch (sync_mode) {
/*
......@@ -597,6 +596,17 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) {
nr_phy_data_t phy_data = {0};
if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
// Start synchronization with a target gNB
if (UE->synch_request.received_synch_request == 1 && UE->target_Nid_cell == -1) {
UE->is_synchronized = 0;
UE->target_Nid_cell = UE->synch_request.synch_req.target_Nid_cell;
clean_UE_ulsch(UE, proc->gNB_id);
} else if (UE->synch_request.received_synch_request == 1 && UE->target_Nid_cell != -1) {
UE->synch_request.received_synch_request = 0;
UE->target_Nid_cell = -1;
}
/* send tick to RLC and PDCP every ms */
if (proc->nr_slot_rx % UE->frame_parms.slots_per_subframe == 0) {
void nr_rlc_tick(int frame, int subframe);
......@@ -622,13 +632,6 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) {
phy_procedures_nrUE_RX(UE, proc, &phy_data);
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
#endif
if(IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa){
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, mac->crnti, proc->frame_rx, proc->nr_slot_rx, 0);
pdcp_run(&ctxt);
}
}
ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
......@@ -815,13 +818,13 @@ void *UE_thread(void *arg) {
if (!UE->is_synchronized) {
readFrame(UE, &timestamp, false);
notifiedFIFO_elt_t *Msg=newNotifiedFIFO_elt(sizeof(syncData_t),0,&nf,UE_synch);
syncData_t *syncMsg=(syncData_t *)NotifiedFifoData(Msg);
syncMsg->UE=UE;
notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch);
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg);
syncMsg->UE = UE;
memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
pushTpool(&(get_nrUE_params()->Tpool), Msg);
trashed_frames=0;
syncRunning=true;
trashed_frames = 0;
syncRunning = true;
continue;
}
......
......@@ -22,6 +22,8 @@
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sched.h>
#include <stdbool.h>
#include <signal.h>
#include "T.h"
#include "assertions.h"
......@@ -59,7 +61,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
#include "pdcp.h"
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
#include "intertask_interface.h"
......@@ -211,6 +213,11 @@ int create_tasks_nrue(uint32_t ue_nb) {
}
itti_wait_ready(0);
// Thread to update the RRC timers (in msec) at UE
pthread_t timers_update;
threadCreate(&timers_update, nr_rrc_timers_update, NULL, "nr_rrc_timer_update", -1, OAI_PRIORITY_RT_LOW);
return 0;
}
......@@ -386,7 +393,7 @@ static void init_pdcp(int ue_id) {
if (get_softmodem_params()->nsa && rlc_module_init(0) != 0) {
LOG_I(RLC, "Problem at RLC initiation \n");
}
pdcp_layer_init();
nr_pdcp_layer_init();
nr_pdcp_module_init(pdcp_initmask, ue_id);
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
......@@ -397,6 +404,27 @@ void *rrc_enb_process_msg(void *notUsed) {
return NULL;
}
static bool stop_immediately = false;
static void trigger_stop(int sig)
{
if (!oai_exit)
itti_wait_tasks_unblock();
}
static void trigger_deregistration(int sig)
{
if (!stop_immediately) {
MessageDef *msg = itti_alloc_new_message(TASK_RRC_UE_SIM, 0, NAS_DEREGISTRATION_REQ);
itti_send_msg_to_task(TASK_NAS_NRUE, 0, 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);
signal(SIGALRM, trigger_stop);
alarm(5);
} else {
itti_wait_tasks_unblock();
}
}
static void get_channel_model_mode() {
paramdef_t GNBParams[] = GNBPARAMS_DESC;
config_get(GNBParams, sizeof(GNBParams)/sizeof(paramdef_t), NULL);
......@@ -426,7 +454,7 @@ int main( int argc, char **argv ) {
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
set_softmodem_sighandler();
//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);
......@@ -550,15 +578,28 @@ int main( int argc, char **argv ) {
// Sleep a while before checking all parameters have been used
// Some are used directly in external threads, asynchronously
sleep(20);
sleep(2);
config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
while(true)
sleep(3600);
// wait for end of program
printf("Entering ITTI signals handler\n");
printf("TYPE <CTRL-C> TO TERMINATE\n");
itti_wait_tasks_end(trigger_deregistration);
printf("Returned from ITTI signal handler\n");
oai_exit=1;
printf("oai_exit=%d\n",oai_exit);
if (ouput_vcd)
vcd_signal_dumper_close();
if (PHY_vars_UE_g && PHY_vars_UE_g[0]) {
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
PHY_VARS_NR_UE *phy_vars = PHY_vars_UE_g[0][CC_id];
if (phy_vars && phy_vars->rfdevice.trx_end_func)
phy_vars->rfdevice.trx_end_func(&phy_vars->rfdevice);
}
}
return 0;
}
......
......@@ -1220,8 +1220,10 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
if (tx_data != NULL) {
uint8_t *dlsch_sdu = (uint8_t *)tx_data->TLVs[0].value.direct;
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
AssertFatal(msgTx->num_pdsch_slot < NUMBER_OF_NR_DLSCH_MAX,"Number of PDSCH PDUs %d exceeded the limit %d\n",
msgTx->num_pdsch_slot, NUMBER_OF_NR_DLSCH_MAX);
AssertFatal(msgTx->num_pdsch_slot < gNB->max_nb_pdsch,
"Number of PDSCH PDUs %d exceeded the limit %d\n",
msgTx->num_pdsch_slot,
gNB->max_nb_pdsch);
handle_nr_nfapi_pdsch_pdu(msgTx, pdsch_pdu, dlsch_sdu);
}
else {
......
......@@ -654,6 +654,10 @@ typedef struct
} fapi_nr_prach_config_t;
typedef struct {
uint16_t target_Nid_cell;
} fapi_nr_synch_request_t;
typedef struct {
uint32_t config_mask;
......
This diff is collapsed.
......@@ -38,7 +38,7 @@
extern openair0_config_t openair0_cfg[MAX_CARDS];
void nr_est_timing_advance_pusch(const NR_DL_FRAME_PARMS *frame_parms, const int32_t *ul_ch_estimates_time, struct delay_s *delay)
void nr_est_timing_advance_pusch(const NR_DL_FRAME_PARMS *frame_parms, const int32_t *ul_ch_estimates_time, NR_ULSCH_delay_t *delay)
{
int max_pos = delay->pusch_delay_max_pos;
int max_val = delay->pusch_delay_max_val;
......@@ -208,57 +208,60 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb
//
// Todo:
// - averaging IIR filter for RX power and noise
void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol, uint8_t nrOfLayers){
int rx_power_tot[NUMBER_OF_NR_ULSCH_MAX];
int rx_power[NUMBER_OF_NR_ULSCH_MAX][NB_ANTENNAS_RX];
unsigned short rx_power_avg_dB[NUMBER_OF_NR_ULSCH_MAX];
unsigned short rx_power_tot_dB[NUMBER_OF_NR_ULSCH_MAX];
void nr_gnb_measurements(PHY_VARS_gNB *gNB,
NR_gNB_ULSCH_t *ulsch,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t nrOfLayers)
{
int rx_power_tot = 0;
unsigned short rx_power_avg_dB;
unsigned short rx_power_tot_dB;
double rx_gain = openair0_cfg[0].rx_gain[0];
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
double rx_gain = openair0_cfg[0].rx_gain[0];
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
PHY_MEASUREMENTS_gNB *meas = &gNB->measurements;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
int ch_offset = fp->ofdm_symbol_size * symbol;
int N_RB_UL = gNB->ulsch[ulsch_id]->harq_processes[harq_pid]->ulsch_pdu.rb_size;
rx_power_tot[ulsch_id] = 0;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
int ch_offset = fp->ofdm_symbol_size * symbol;
int N_RB_UL = ulsch->harq_process->ulsch_pdu.rb_size;
ulsch_measurements_gNB *ulsch_measurements = &ulsch->ulsch_measurements;
int rx_power[fp->nb_antennas_rx];
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++){
rx_power[ulsch_id][aarx] = 0;
rx_power[aarx] = 0;
for (int aatx = 0; aatx < nrOfLayers; aatx++){
ulsch_measurements->rx_spatial_power[aatx][aarx] =
(signal_energy_nodc(&pusch_vars->ul_ch_estimates[aatx * fp->nb_antennas_rx + aarx][ch_offset],
N_RB_UL * NR_NB_SC_PER_RB));
meas->rx_spatial_power[ulsch_id][aatx][aarx] = (signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aatx*fp->nb_antennas_rx+aarx][ch_offset], N_RB_UL * NR_NB_SC_PER_RB));
if (meas->rx_spatial_power[ulsch_id][aatx][aarx] < 0) {
meas->rx_spatial_power[ulsch_id][aatx][aarx] = 0;
if (ulsch_measurements->rx_spatial_power[aatx][aarx] < 0) {
ulsch_measurements->rx_spatial_power[aatx][aarx] = 0;
}
meas->rx_spatial_power_dB[ulsch_id][aatx][aarx] = (unsigned short) dB_fixed(meas->rx_spatial_power[ulsch_id][aatx][aarx]);
rx_power[ulsch_id][aarx] += meas->rx_spatial_power[ulsch_id][aatx][aarx];
ulsch_measurements->rx_spatial_power_dB[aatx][aarx] =
(unsigned short)dB_fixed(ulsch_measurements->rx_spatial_power[aatx][aarx]);
rx_power[aarx] += ulsch_measurements->rx_spatial_power[aatx][aarx];
}
LOG_D(PHY, "[ULSCH ID %d] RX power in antenna %d = %d\n", ulsch_id, aarx, rx_power[ulsch_id][aarx]);
rx_power_tot[ulsch_id] += rx_power[ulsch_id][aarx];
LOG_D(PHY, "[RNTI %04x] RX power in antenna %d = %d\n", ulsch->rnti, aarx, rx_power[aarx]);
rx_power_tot += rx_power[aarx];
}
rx_power_tot_dB[ulsch_id] = (unsigned short) dB_fixed(rx_power_tot[ulsch_id]);
rx_power_avg_dB[ulsch_id] = rx_power_tot_dB[ulsch_id];
meas->wideband_cqi_tot[ulsch_id] = dB_fixed2(rx_power_tot[ulsch_id], meas->n0_power_tot);
meas->rx_rssi_dBm[ulsch_id] = rx_power_avg_dB[ulsch_id] + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
LOG_D(PHY, "[ULSCH %d] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d, RX Power tot %d\n",
ulsch_id,
meas->rx_rssi_dBm[ulsch_id],
rx_power_avg_dB[ulsch_id],
N_RB_UL,
meas->wideband_cqi_tot[ulsch_id],
meas->n0_power_tot,
rx_power_tot[ulsch_id]);
rx_power_tot_dB = (unsigned short)dB_fixed(rx_power_tot);
rx_power_avg_dB = rx_power_tot_dB;
ulsch_measurements->wideband_cqi_tot = dB_fixed2(rx_power_tot, meas->n0_power_tot);
ulsch_measurements->rx_rssi_dBm =
rx_power_avg_dB + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
LOG_D(PHY,
"[RNTI %04x] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d, RX Power tot %d\n",
ulsch->rnti,
ulsch_measurements->rx_rssi_dBm,
rx_power_avg_dB,
N_RB_UL,
ulsch_measurements->wideband_cqi_tot,
meas->n0_power_tot,
rx_power_tot);
}
......@@ -130,7 +130,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
debug_ch_est = fopen("debug_ch_est.txt","w");
#endif
//uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1];
c16_t **ul_ch_estimates = (c16_t **) gNB->pusch_vars[ul_id]->ul_ch_estimates;
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ul_id];
c16_t **ul_ch_estimates = (c16_t **)pusch_vars->ul_ch_estimates;
const int symbolSize = gNB->frame_parms.ofdm_symbol_size;
const int soffset = (Ns&3)*gNB->frame_parms.symbols_per_slot*symbolSize;
const int nushift = (p>>1)&1;
......@@ -187,7 +188,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
c16_t ul_ls_est[symbolSize] __attribute__((aligned(32)));
memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize);
memset(&gNB->measurements.delay[ul_id], 0, sizeof(gNB->measurements.delay[ul_id]));
NR_ULSCH_delay_t *delay = &gNB->ulsch[ul_id].delay;
memset(delay, 0, sizeof(*delay));
for (int aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) {
c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[aarx][symbol_offset];
......@@ -228,17 +230,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
pilot_cnt += 2;
}
freq2time(symbolSize,
(int16_t *) ul_ls_est,
(int16_t *) gNB->pusch_vars[ul_id]->ul_ch_estimates_time[aarx]);
freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t *)pusch_vars->ul_ch_estimates_time[aarx]);
nr_est_timing_advance_pusch(&gNB->frame_parms, gNB->pusch_vars[ul_id]->ul_ch_estimates_time[aarx], &gNB->measurements.delay[ul_id]);
int delay = gNB->measurements.delay[ul_id].pusch_est_delay;
int delay_idx = get_delay_idx(delay);
nr_est_timing_advance_pusch(&gNB->frame_parms, pusch_vars->ul_ch_estimates_time[aarx], delay);
int pusch_delay = delay->pusch_est_delay;
int delay_idx = get_delay_idx(pusch_delay);
c16_t *ul_delay_table = gNB->frame_parms.ul_delay_table[delay_idx];
#ifdef DEBUG_PUSCH
printf("Estimated delay = %i\n", delay >> 1);
printf("Estimated delay = %i\n", pusch_delay >> 1);
#endif
pilot_cnt = 0;
......@@ -277,7 +277,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
// Revert delay
pilot_cnt = 0;
ul_ch = &ul_ch_estimates[p * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset];
int inv_delay_idx = get_delay_idx(-delay);
int inv_delay_idx = get_delay_idx(-pusch_delay);
c16_t *ul_inv_delay_table = gNB->frame_parms.ul_delay_table[inv_delay_idx];
for (int n = 0; n < 3 * nb_rb_pusch; n++) {
for (int k_line = 0; k_line <= 1; k_line++) {
......@@ -310,10 +310,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
}
// Delay compensation
freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t *)gNB->pusch_vars[ul_id]->ul_ch_estimates_time[aarx]);
nr_est_timing_advance_pusch(&gNB->frame_parms, gNB->pusch_vars[ul_id]->ul_ch_estimates_time[aarx], &gNB->measurements.delay[ul_id]);
int delay = gNB->measurements.delay[ul_id].pusch_est_delay;
int delay_idx = get_delay_idx(-delay);
freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t *)pusch_vars->ul_ch_estimates_time[aarx]);
nr_est_timing_advance_pusch(&gNB->frame_parms, pusch_vars->ul_ch_estimates_time[aarx], delay);
int pusch_delay = delay->pusch_est_delay;
int delay_idx = get_delay_idx(-pusch_delay);
c16_t *ul_delay_table = gNB->frame_parms.ul_delay_table[delay_idx];
for (int n = 0; n < nb_rb_pusch * NR_NB_SC_PER_RB; n++) {
ul_ch[n] = c16mulShift(ul_ls_est[n], ul_delay_table[n % 6], 8);
......@@ -532,7 +532,9 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
uint8_t ulsch_id,
uint8_t nr_tti_rx,
unsigned char symbol,
uint32_t nb_re_pusch) {
uint32_t nb_re_pusch)
{
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ulsch_id];
//#define DEBUG_UL_PTRS 1
int32_t *ptrs_re_symbol = NULL;
int8_t ret = 0;
......@@ -542,16 +544,16 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
uint8_t *L_ptrs = &rel15_ul->pusch_ptrs.ptrs_time_density;
uint8_t *K_ptrs = &rel15_ul->pusch_ptrs.ptrs_freq_density;
uint16_t *dmrsSymbPos = &rel15_ul->ul_dmrs_symb_pos;
uint16_t *ptrsSymbPos = &gNB->pusch_vars[ulsch_id]->ptrs_symbols;
uint8_t *ptrsSymbIdx = &gNB->pusch_vars[ulsch_id]->ptrs_symbol_index;
uint16_t *ptrsSymbPos = &pusch_vars->ptrs_symbols;
uint8_t *ptrsSymbIdx = &pusch_vars->ptrs_symbol_index;
uint8_t *dmrsConfigType = &rel15_ul->dmrs_config_type;
uint16_t *nb_rb = &rel15_ul->rb_size;
uint8_t *ptrsReOffset = &rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset;
/* loop over antennas */
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
c16_t *phase_per_symbol = (c16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx];
ptrs_re_symbol = &gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot;
c16_t *phase_per_symbol = (c16_t *)pusch_vars->ptrs_phase_per_slot[aarx];
ptrs_re_symbol = &pusch_vars->ptrs_re_per_slot;
*ptrs_re_symbol = 0;
phase_per_symbol[symbol].i = 0;
/* set DMRS estimates to 0 angle with magnitude 1 */
......@@ -584,13 +586,17 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
/*------------------------------------------------------------------------------------------------------- */
/* 1) Estimate common phase error per PTRS symbol */
/*------------------------------------------------------------------------------------------------------- */
nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb,
nr_ptrs_cpe_estimation(*K_ptrs,
*ptrsReOffset,
*dmrsConfigType,
*nb_rb,
rel15_ul->rnti,
nr_tti_rx,
symbol,frame_parms->ofdm_symbol_size,
(int16_t *)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
symbol,
frame_parms->ofdm_symbol_size,
(int16_t *)&pusch_vars->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
gNB->nr_gold_pusch_dmrs[rel15_ul->scid][nr_tti_rx][symbol],
(int16_t*)&phase_per_symbol[symbol],
(int16_t *)&phase_per_symbol[symbol],
ptrs_re_symbol);
}
......@@ -608,7 +614,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
}
#ifdef DEBUG_UL_PTRS
LOG_M("ptrsEstUl.m","est",gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
LOG_M("ptrsEstUl.m", "est", pusch_vars->ptrs_phase_per_slot[aarx], frame_parms->symbols_per_slot, 1, 1);
LOG_M("rxdataF_bf_ptrs_comp_ul.m","bf_ptrs_cmp",
&gNB->pusch_vars[0]->rxdataF_comp[aarx][rel15_ul->start_symbol_index * NR_NB_SC_PER_RB * rel15_ul->rb_size],
rel15_ul->nr_of_symbols * NR_NB_SC_PER_RB * rel15_ul->rb_size,1,1);
......@@ -624,10 +630,11 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
#ifdef DEBUG_UL_PTRS
printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i);
#endif
rotate_cpx_vector((c16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
rotate_cpx_vector((c16_t *)&pusch_vars->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
&phase_per_symbol[i],
(c16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
((*nb_rb) * NR_NB_SC_PER_RB), 15);
(c16_t *)&pusch_vars->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
((*nb_rb) * NR_NB_SC_PER_RB),
15);
}// if not DMRS Symbol
}// symbol loop
}// last symbol check
......
......@@ -53,9 +53,15 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot,int first_symb,int num_symb);
void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol, uint8_t nrOfLayers);
void nr_gnb_measurements(PHY_VARS_gNB *gNB,
NR_gNB_ULSCH_t *ulsch,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t nrOfLayers);
void nr_est_timing_advance_pusch(const NR_DL_FRAME_PARMS *frame_parms, const int32_t *ul_ch_estimates_time, struct delay_s *delay);
void nr_est_timing_advance_pusch(const NR_DL_FRAME_PARMS *frame_parms,
const int32_t *ul_ch_estimates_time,
NR_ULSCH_delay_t *delay);
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]);
......
......@@ -126,12 +126,7 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue);
void free_context_pss_nr(void);
int set_pss_nr(int ofdm_symbol_size);
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change);
int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms,
int fo_flag,
int is,
int *eNB_id,
int *f_off);
int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, int is);
#endif
#undef EXTERN
......
......@@ -75,7 +75,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
time_stats_t *dlsch_segmentation_stats=&gNB->dlsch_segmentation_stats;
for (int dlsch_id=0; dlsch_id<msgTx->num_pdsch_slot; dlsch_id++) {
dlsch = msgTx->dlsch[dlsch_id][0];
dlsch = &msgTx->dlsch[dlsch_id][0];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
......@@ -567,21 +567,16 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
}
void dump_pdsch_stats(FILE *fd,PHY_VARS_gNB *gNB) {
for (int i=0;i<NUMBER_OF_NR_SCH_STATS_MAX;i++)
if (gNB->dlsch_stats[i].rnti > 0 && gNB->dlsch_stats[i].frame != gNB->dlsch_stats[i].dump_frame) {
gNB->dlsch_stats[i].dump_frame = gNB->dlsch_stats[i].frame;
fprintf(fd,"DLSCH RNTI %x: current_Qm %d, current_RI %d, total_bytes TX %d\n",
gNB->dlsch_stats[i].rnti,
gNB->dlsch_stats[i].current_Qm,
gNB->dlsch_stats[i].current_RI,
gNB->dlsch_stats[i].total_bytes_tx);
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
NR_gNB_PHY_STATS_t *stats = &gNB->phy_stats[i];
if (stats->active && stats->frame != stats->dlsch_stats.dump_frame) {
stats->dlsch_stats.dump_frame = stats->frame;
fprintf(fd,
"DLSCH RNTI %x: current_Qm %d, current_RI %d, total_bytes TX %d\n",
stats->rnti,
stats->dlsch_stats.current_Qm,
stats->dlsch_stats.current_RI,
stats->dlsch_stats.total_bytes_tx);
}
}
void clear_pdsch_stats(PHY_VARS_gNB *gNB) {
for (int i = 0;i < NUMBER_OF_NR_SCH_STATS_MAX; i++)
memset((void*)&gNB->dlsch_stats[i],0,sizeof(gNB->dlsch_stats[i]));
}
}
......@@ -52,8 +52,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
NR_gNB_SCH_STATS_t *find_nr_dlsch_stats(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
......@@ -77,6 +75,4 @@ void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size);
void dump_pdsch_stats(FILE *fd,PHY_VARS_gNB *gNB);
void clear_pdsch_stats(PHY_VARS_gNB *gNB);
#endif
......@@ -48,13 +48,8 @@
//#define DEBUG_DLSCH_CODING
//#define DEBUG_DLSCH_FREE 1
void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,
uint16_t N_RB,
const NR_DL_FRAME_PARMS* frame_parms) {
NR_gNB_DLSCH_t *dlsch = *dlschptr;
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARMS *frame_parms)
{
int max_layers = (frame_parms->nb_antennas_tx<NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*max_layers;
......@@ -92,14 +87,10 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,
}
free(dlsch->txdataF);
free(dlsch->ue_spec_bf_weights);
free(dlsch);
*dlschptr = NULL;
}
NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
uint16_t N_RB) {
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
{
int max_layers = (frame_parms->nb_antennas_tx<NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*max_layers; //number of segments to be allocated
......@@ -110,34 +101,32 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
LOG_D(PHY,"Allocating %d segments (MAX %d, N_PRB %d)\n",a_segments,MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER,N_RB);
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
NR_gNB_DLSCH_t *dlsch = malloc16(sizeof(NR_gNB_DLSCH_t));
AssertFatal(dlsch, "cannot allocate dlsch\n");
bzero(dlsch,sizeof(NR_gNB_DLSCH_t));
NR_gNB_DLSCH_t dlsch;
int txdataf_size = frame_parms->N_RB_DL*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8; // max pdsch encoded length for each layer
dlsch->txdataF = (int32_t **)malloc16(max_layers*sizeof(int32_t *));
dlsch.txdataF = (int32_t **)malloc16(max_layers * sizeof(int32_t *));
dlsch->ue_spec_bf_weights = (int32_t ***)malloc16(max_layers*sizeof(int32_t **));
dlsch.ue_spec_bf_weights = (int32_t ***)malloc16(max_layers * sizeof(int32_t **));
for (int layer=0; layer<max_layers; layer++) {
dlsch->ue_spec_bf_weights[layer] = (int32_t **)malloc16(64*sizeof(int32_t *));
dlsch.ue_spec_bf_weights[layer] = (int32_t **)malloc16(64 * sizeof(int32_t *));
for (int aa=0; aa<64; aa++) {
dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
dlsch.ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES * sizeof(int32_t));
for (int re=0; re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
dlsch.ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
}
}
dlsch->txdataF[layer] = (int32_t *)malloc16((txdataf_size)*sizeof(int32_t));
dlsch.txdataF[layer] = (int32_t *)malloc16((txdataf_size) * sizeof(int32_t));
}
int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
dlsch->mod_symbs = (int32_t **)malloc16(nb_codewords*sizeof(int32_t *));
dlsch.mod_symbs = (int32_t **)malloc16(nb_codewords * sizeof(int32_t *));
for (int q=0; q<nb_codewords; q++)
dlsch->mod_symbs[q] = (int32_t *)malloc16(txdataf_size*max_layers*sizeof(int32_t));
dlsch.mod_symbs[q] = (int32_t *)malloc16(txdataf_size * max_layers * sizeof(int32_t));
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
NR_DL_gNB_HARQ_t *harq = &dlsch.harq_process;
bzero(harq, sizeof(NR_DL_gNB_HARQ_t));
harq->b = malloc16(dlsch_bytes);
AssertFatal(harq->b, "cannot allocate memory for harq->b\n");
......@@ -167,7 +156,6 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) {
AssertFatal(dlsch!=NULL,"dlsch is null\n");
dlsch->rnti = 0;
dlsch->active = 0;
}
......@@ -277,10 +265,15 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
uint8_t slot,
NR_DL_gNB_HARQ_t *harq,
NR_DL_FRAME_PARMS *frame_parms,
unsigned char * output,
time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput,
time_stats_t *dlsch_rate_matching_stats,time_stats_t *dlsch_interleaving_stats,
time_stats_t *dlsch_segmentation_stats) {
unsigned char *output,
time_stats_t *tinput,
time_stats_t *tprep,
time_stats_t *tparity,
time_stats_t *toutput,
time_stats_t *dlsch_rate_matching_stats,
time_stats_t *dlsch_interleaving_stats,
time_stats_t *dlsch_segmentation_stats)
{
encoder_implemparams_t impp;
impp.output=output;
unsigned int crc=1;
......@@ -289,29 +282,18 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
uint32_t A = rel15->TBSize[0]<<3;
unsigned char *a=harq->pdu;
if ( rel15->rnti != SI_RNTI)
if (rel15->rnti != SI_RNTI)
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], WS_C_RNTI, rel15->rnti, frame, slot,0, 0);
NR_gNB_SCH_STATS_t *stats=NULL;
int first_free=-1;
for (int i=0; i<NUMBER_OF_NR_SCH_STATS_MAX; i++) {
if (gNB->dlsch_stats[i].rnti == 0 && first_free == -1) {
first_free = i;
stats=&gNB->dlsch_stats[i];
}
if (gNB->dlsch_stats[i].rnti == rel15->rnti) {
stats=&gNB->dlsch_stats[i];
break;
}
}
NR_gNB_PHY_STATS_t *phy_stats = NULL;
if (rel15->rnti != 0xFFFF)
phy_stats = get_phy_stats(gNB, rel15->rnti);
if (stats) {
stats->rnti = rel15->rnti;
stats->total_bytes_tx += rel15->TBSize[0];
stats->current_RI = rel15->nrOfLayers;
stats->current_Qm = rel15->qamModOrder[0];
if (phy_stats) {
phy_stats->frame = frame;
phy_stats->dlsch_stats.total_bytes_tx += rel15->TBSize[0];
phy_stats->dlsch_stats.current_RI = rel15->nrOfLayers;
phy_stats->dlsch_stats.current_Qm = rel15->qamModOrder[0];
}
int max_bytes = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers*1056;
......
......@@ -44,16 +44,13 @@ void nr_emulate_dlsch_payload(uint8_t* pdu, uint16_t size) {
*(pdu+i) = (uint8_t)rand();
}
void nr_fill_dlsch(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu) {
NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[msgTx->num_pdsch_slot][0];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
void nr_fill_dlsch(processingData_L1tx_t *msgTx, nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, uint8_t *sdu)
{
NR_gNB_DLSCH_t *dlsch = &msgTx->dlsch[msgTx->num_pdsch_slot][0];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
/// DLSCH struct
memcpy((void*)&harq->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu));
msgTx->num_pdsch_slot++;
AssertFatal(sdu!=NULL,"sdu is null\n");
AssertFatal(sdu != NULL, "sdu is null\n");
harq->pdu = sdu;
}
......@@ -40,7 +40,6 @@
#include "PHY/defs_nr_common.h"
void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
uint32_t n_id,
uint8_t n_hop,
......
......@@ -38,6 +38,7 @@
#define NR_PBCH_PDU_BITS 24
NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti);
int nr_generate_prs(uint32_t **nr_gold_prs,
c16_t *txdataF,
......@@ -107,10 +108,9 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
*/
void nr_init_pbch_interleaver(uint8_t *interleaver);
NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
uint16_t N_RB);
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB);
void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB, const NR_DL_FRAME_PARMS* frame_parms);
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARMS *frame_parms);
/** \brief This function is the top-level entry point to PUSCH demodulation, after frequency-domain transformation and channel estimation. It performs
- RB extraction (signal and channel estimates)
......@@ -269,6 +269,9 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
uint8_t symbol,
uint8_t mod_order);
void reset_active_stats(PHY_VARS_gNB *gNB, int frame);
void reset_active_ulsch(PHY_VARS_gNB *gNB, int frame);
void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
......@@ -304,27 +307,11 @@ void nr_fill_prach_ru(RU_t *ru,
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, find_type_t type);
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type);
NR_gNB_PUCCH_t *new_gNB_pucch(void);
void free_gNB_pucch(NR_gNB_PUCCH_t *pucch);
void nr_fill_pucch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pucch_pdu_t *pucch_pdu);
int nr_find_pucch(uint16_t rnti,
int frame,
int slot,
PHY_VARS_gNB *gNB);
NR_gNB_SRS_t *new_gNB_srs(void);
void free_gNB_srs(NR_gNB_SRS_t *srs);
int nr_find_srs(rnti_t rnti,
frame_t frame,
slot_t slot,
PHY_VARS_gNB *gNB);
void nr_fill_srs(PHY_VARS_gNB *gNB,
frame_t frame,
slot_t slot,
......
......@@ -34,57 +34,74 @@
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i = 0; i < NUMBER_OF_NR_ULSCH_MAX; i++) {
AssertFatal(gNB->ulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i);
LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i]->harq_mask,gNB->ulsch[i]->rnti,first_free_index);
if ((gNB->ulsch[i]->harq_mask >0) &&
(gNB->ulsch[i]->rnti==rnti)) return i;
else if ((gNB->ulsch[i]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid)
{
int16_t first_free_index = -1;
AssertFatal(gNB != NULL, "gNB is null\n");
NR_gNB_ULSCH_t *ulsch = NULL;
for (int i = 0; i < gNB->max_nb_pusch; i++) {
ulsch = &gNB->ulsch[i];
AssertFatal(ulsch != NULL, "gNB->ulsch[%d] is null\n", i);
if (!ulsch->active) {
if (first_free_index == -1)
first_free_index = i;
} else {
// if there is already an active ULSCH for this RNTI and HARQ_PID
if ((ulsch->harq_pid == pid) && (ulsch->rnti == rnti))
return ulsch;
}
}
if (type == SEARCH_EXIST) return -1;
if (first_free_index != -1)
gNB->ulsch[first_free_index]->rnti = 0;
return first_free_index;
}
ulsch = &gNB->ulsch[first_free_index];
void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pusch_pdu_t *ulsch_pdu) {
int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal((ulsch_id >= 0) && (ulsch_id < NUMBER_OF_NR_ULSCH_MAX),
"illegal or no ulsch_id found!!! rnti %04x ulsch_id %d\n",ulsch_pdu->rnti,ulsch_id);
return ulsch;
}
NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id];
void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t *ulsch_pdu)
{
int harq_pid = ulsch_pdu->pusch_data.harq_process_id;
NR_gNB_ULSCH_t *ulsch = find_nr_ulsch(gNB, ulsch_pdu->rnti, harq_pid);
AssertFatal(ulsch, "No ulsch_id found for rnti %04x\n", ulsch_pdu->rnti);
ulsch->rnti = ulsch_pdu->rnti;
//ulsch->rnti_type;
ulsch->harq_mask |= 1<<harq_pid;
NR_UL_gNB_HARQ_t *harq = ulsch->harq_processes[harq_pid];
harq->frame=frame;
harq->slot=slot;
harq->handled = 0;
harq->status= NR_ACTIVE;
harq->new_rx = ulsch_pdu->pusch_data.new_data_indicator;
LOG_D(PHY,"ULSCH ID %d RNTI %x HARQ PID %d new data indicator %d\n",ulsch_id, ulsch_pdu->rnti, harq_pid, ulsch_pdu->pusch_data.new_data_indicator);
if (harq->new_rx)
ulsch->harq_pid = harq_pid;
ulsch->handled = 0;
ulsch->active = true;
ulsch->frame = frame;
ulsch->slot = slot;
NR_UL_gNB_HARQ_t *harq = ulsch->harq_process;
if (ulsch_pdu->pusch_data.new_data_indicator)
harq->harq_to_be_cleared = true;
LOG_D(PHY,
"%d.%d RNTI %x HARQ PID %d new data indicator %d\n",
frame,
slot,
ulsch_pdu->rnti,
harq_pid,
ulsch_pdu->pusch_data.new_data_indicator);
if (ulsch_pdu->pusch_data.new_data_indicator)
harq->round = 0;
else
harq->round++;
memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
memcpy(&ulsch->harq_process->ulsch_pdu, ulsch_pdu, sizeof(ulsch->harq_process->ulsch_pdu));
LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
LOG_D(PHY, "Initializing nFAPI for ULSCH, harq_pid %d\n", harq_pid);
}
void reset_active_ulsch(PHY_VARS_gNB *gNB, int frame)
{
// deactivate ULSCH structure after a given number of frames
// no activity on this structure for NUMBER_FRAMES_PHY_UE_INACTIVE
// assuming UE disconnected or some other error occurred
for (int i = 0; i < gNB->max_nb_pusch; i++) {
NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[i];
if (ulsch->active && (((frame - ulsch->frame + 1024) % 1024) > NUMBER_FRAMES_PHY_UE_INACTIVE))
ulsch->active = false;
}
}
void nr_ulsch_unscrambling(int16_t* llr, uint32_t size, uint32_t Nid, uint32_t n_RNTI)
......@@ -92,11 +109,7 @@ void nr_ulsch_unscrambling(int16_t* llr, uint32_t size, uint32_t Nid, uint32_t n
nr_codeword_unscrambling(llr, size, 0, Nid, n_RNTI);
}
void nr_ulsch_layer_demapping(int16_t *llr_cw,
uint8_t Nl,
uint8_t mod_order,
uint32_t length,
int16_t **llr_layers)
void nr_ulsch_layer_demapping(int16_t *llr_cw, uint8_t Nl, uint8_t mod_order, uint32_t length, int16_t **llr_layers)
{
switch (Nl) {
......@@ -115,63 +128,55 @@ void nr_ulsch_layer_demapping(int16_t *llr_cw,
}
break;
default:
AssertFatal(0, "Not supported number of layers %d\n", Nl);
AssertFatal(0, "Not supported number of layers %d\n", Nl);
}
}
void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB) {
for (int i = 0;i < NUMBER_OF_NR_SCH_STATS_MAX;i++) {
if (gNB->ulsch_stats[i].rnti>0 && gNB->ulsch_stats[i].frame != gNB->ulsch_stats[i].dump_frame) {
gNB->ulsch_stats[i].dump_frame = gNB->ulsch_stats[i].frame;
for (int aa=0;aa<gNB->frame_parms.nb_antennas_rx;aa++)
if (aa==0) fprintf(fd,"ULSCH RNTI %4x, %d.%d: ulsch_power[%d] %d,%d ulsch_noise_power[%d] %d.%d, sync_pos %d\n",
gNB->ulsch_stats[i].rnti,gNB->ulsch_stats[i].frame,gNB->ulsch_stats[i].dump_frame,
aa,gNB->ulsch_stats[i].power[aa]/10,gNB->ulsch_stats[i].power[aa]%10,
aa,gNB->ulsch_stats[i].noise_power[aa]/10,gNB->ulsch_stats[i].noise_power[aa]%10,
gNB->ulsch_stats[i].sync_pos);
else fprintf(fd," ulsch_power[%d] %d.%d, ulsch_noise_power[%d] %d.%d\n",
aa,gNB->ulsch_stats[i].power[aa]/10,gNB->ulsch_stats[i].power[aa]%10,
aa,gNB->ulsch_stats[i].noise_power[aa]/10,gNB->ulsch_stats[i].noise_power[aa]%10);
fprintf(fd," round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, DTX %d, current_Qm %d, current_RI %d, total_bytes RX/SCHED %d/%d\n",
gNB->ulsch_stats[i].round_trials[0],
(double)gNB->ulsch_stats[i].round_trials[1]/gNB->ulsch_stats[i].round_trials[0],
gNB->ulsch_stats[i].round_trials[1],
(double)gNB->ulsch_stats[i].round_trials[2]/gNB->ulsch_stats[i].round_trials[0],
gNB->ulsch_stats[i].round_trials[2],
(double)gNB->ulsch_stats[i].round_trials[3]/gNB->ulsch_stats[i].round_trials[0],
gNB->ulsch_stats[i].round_trials[3],
gNB->ulsch_stats[i].DTX,
gNB->ulsch_stats[i].current_Qm,
gNB->ulsch_stats[i].current_RI,
gNB->ulsch_stats[i].total_bytes_rx,
gNB->ulsch_stats[i].total_bytes_tx);
void dump_pusch_stats(FILE *fd, PHY_VARS_gNB *gNB)
{
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
NR_gNB_PHY_STATS_t *stats = &gNB->phy_stats[i];
if (stats->active && stats->frame != stats->ulsch_stats.dump_frame) {
stats->ulsch_stats.dump_frame = stats->frame;
for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++)
if (aa == 0)
fprintf(fd,
"ULSCH RNTI %4x, %d: ulsch_power[%d] %d,%d ulsch_noise_power[%d] %d.%d, sync_pos %d\n",
stats->rnti,
stats->frame,
aa,
stats->ulsch_stats.power[aa] / 10,
stats->ulsch_stats.power[aa] % 10,
aa,
stats->ulsch_stats.noise_power[aa] / 10,
stats->ulsch_stats.noise_power[aa] % 10,
stats->ulsch_stats.sync_pos);
else
fprintf(fd,
" ulsch_power[%d] %d.%d, ulsch_noise_power[%d] %d.%d\n",
aa,
stats->ulsch_stats.power[aa] / 10,
stats->ulsch_stats.power[aa] % 10,
aa,
stats->ulsch_stats.noise_power[aa] / 10,
stats->ulsch_stats.noise_power[aa] % 10);
int *rt = stats->ulsch_stats.round_trials;
fprintf(fd,
" round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, DTX %d, current_Qm %d, current_RI %d, total_bytes "
"RX/SCHED %d/%d\n",
rt[0],
(double)rt[1] / rt[0],
rt[1],
(double)rt[2] / rt[0],
rt[2],
(double)rt[3] / rt[0],
rt[3],
stats->ulsch_stats.DTX,
stats->ulsch_stats.current_Qm,
stats->ulsch_stats.current_RI,
stats->ulsch_stats.total_bytes_rx,
stats->ulsch_stats.total_bytes_tx);
}
}
}
void clear_pusch_stats(PHY_VARS_gNB *gNB) {
for (int i = 0; i < NUMBER_OF_NR_ULSCH_MAX; i++)
memset((void*)&gNB->ulsch_stats[i],0,sizeof(gNB->ulsch_stats[i]));
}
NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch) {
NR_gNB_SCH_STATS_t *stats=NULL;
int first_free=-1;
for (int i = 0; i < NUMBER_OF_NR_ULSCH_MAX; i++) {
if (gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
first_free = i;
stats=&gNB->ulsch_stats[i];
}
if (gNB->ulsch_stats[i].rnti == ulsch->rnti) {
stats=&gNB->ulsch_stats[i];
break;
}
}
return(stats);
}
}
......@@ -33,10 +33,9 @@
#include "PHY/defs_gNB.h"
#include "common/utils/threadPool/thread-pool.h"
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch, uint16_t N_RB_UL);
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL);
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL);
NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL);
/*! \brief Perform PUSCH decoding. TS 38.212 V15.4.0 subclause 6.2
@param phy_vars_gNB, Pointer to PHY data structure for gNB
......@@ -82,11 +81,11 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
int slot_rx,
int UE_id,
uint8_t harq_pid);
int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid);
void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB);
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
void clear_pusch_stats(PHY_VARS_gNB *gNB);
NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch);
This diff is collapsed.
......@@ -44,55 +44,21 @@
//#define SRS_DEBUG
NR_gNB_SRS_t *new_gNB_srs(void){
NR_gNB_SRS_t *srs;
srs = (NR_gNB_SRS_t *)malloc16(sizeof(NR_gNB_SRS_t));
srs->active = 0;
return (srs);
}
void free_gNB_srs(NR_gNB_SRS_t *srs)
void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu)
{
free_and_zero(srs);
}
int nr_find_srs(rnti_t rnti,
frame_t frame,
slot_t slot,
PHY_VARS_gNB *gNB) {
AssertFatal(gNB!=NULL,"gNB is null\n");
int index = -1;
bool found = false;
for (int i = 0; i < gNB->max_nb_srs; i++) {
AssertFatal(gNB->srs[i]!=NULL,"gNB->srs[%d] is null\n",i);
if ((gNB->srs[i]->active>0) &&
(gNB->srs[i]->srs_pdu.rnti==rnti) &&
(gNB->srs[i]->frame==frame) &&
(gNB->srs[i]->slot==slot)) return(i);
else if ((gNB->srs[i]->active == 0) && (index==-1)) index=i;
NR_gNB_SRS_t *srs = &gNB->srs[i];
if (srs->active == 0) {
found = true;
srs->frame = frame;
srs->slot = slot;
srs->active = 1;
memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t));
break;
}
}
if (index==-1)
LOG_E(PHY,"SRS list is full\n");
return(index);
}
void nr_fill_srs(PHY_VARS_gNB *gNB,
frame_t frame,
slot_t slot,
nfapi_nr_srs_pdu_t *srs_pdu) {
int id = nr_find_srs(srs_pdu->rnti,frame,slot,gNB);
AssertFatal((id >= 0) && (id < gNB->max_nb_srs),
"invalid id found for srs !!! rnti %04x id %d\n",srs_pdu->rnti,id);
NR_gNB_SRS_t *srs = gNB->srs[id];
srs->frame = frame;
srs->slot = slot;
srs->active = 1;
memcpy((void*)&srs->srs_pdu, (void*)srs_pdu, sizeof(nfapi_nr_srs_pdu_t));
AssertFatal(found, "SRS list is full\n");
}
int nr_get_srs_signal(PHY_VARS_gNB *gNB,
......
......@@ -300,11 +300,11 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
/* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
for(int i=0; i<4;i++)
for (int i = 0; i < NR_N_SYMBOLS_SSB; i++)
nr_slot_fep_init_sync(ue,
proc,
i,
is*fp->samples_per_frame+ue->ssb_offset,
is * fp->samples_per_frame + ue->ssb_offset,
false,
rxdataF);
......@@ -522,6 +522,10 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
}
if (ue->target_Nid_cell != -1) {
return ret;
}
// if stand alone and sync on ssb do sib1 detection as part of initial sync
if (sa==1 && ret==0) {
nr_ue_dlsch_init(phy_data.dlsch, 1, ue->max_ldpc_iterations);
......
......@@ -251,6 +251,8 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t Nl);
int8_t clean_UE_ulsch(PHY_VARS_NR_UE *UE, uint8_t gNB_id);
void nr_dlsch_unscrambling(int16_t* llr,
uint32_t size,
uint8_t q,
......@@ -313,7 +315,7 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, char* bu
@param mode current running mode
*/
int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *phy_vars_ue,
PHY_VARS_NR_UE *phy_vars_ue,
int n_frames,
int sa);
......
......@@ -662,3 +662,15 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
////////////////////////////////////////////////////
return 0;
}
int8_t clean_UE_ulsch(PHY_VARS_NR_UE *UE, uint8_t gNB_id)
{
for (int harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) {
NR_UL_UE_HARQ_t *ul_harq_process = &UE->ul_harq_processes[harq_pid];
ul_harq_process->tx_status = NEW_TRANSMISSION_HARQ;
ul_harq_process->status = SCH_IDLE;
ul_harq_process->round = 0;
ul_harq_process->first_tx = 1;
}
return 0;
}
......@@ -555,12 +555,8 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_IN);
synchro_position = pss_search_time_nr(rxdata,
frame_parms,
fo_flag,
is,
(int *)&PHY_vars_UE->common_vars.eNb_id,
(int *)&PHY_vars_UE->common_vars.freq_offset);
synchro_position = pss_search_time_nr(rxdata, PHY_vars_UE, fo_flag, is);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_OUT);
......@@ -605,7 +601,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
*
* NAME : pss_search_time_nr
*
* PARAMETERS : received buffer
* PARAMETERS : received buffer in time domain
* frame parameters
*
* RETURN : position of detected pss
......@@ -651,17 +647,15 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
*
*********************************************************************/
int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms,
int fo_flag,
int is,
int *eNB_id,
int *f_off)
int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, int is)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int *eNB_id = (int *)&ue->common_vars.eNb_id;
int *f_off = (int *)&ue->common_vars.freq_offset;
unsigned int n, ar, peak_position, pss_source;
int64_t peak_value;
int64_t avg[NUMBER_PSS_SEQUENCE]={0};
double ffo_est=0;
int64_t avg[NUMBER_PSS_SEQUENCE] = {0};
double ffo_est = 0;
// performing the correlation on a frame length plus one symbol for the first of the two frame
// to take into account the possibility of PSS in between the two frames
......@@ -692,7 +686,14 @@ int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain
/* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
uint16_t pss_index_start = 0;
uint16_t pss_index_end = NUMBER_PSS_SEQUENCE;
if (ue->target_Nid_cell != -1) {
pss_index_start = GET_NID2(ue->target_Nid_cell);
pss_index_end = pss_index_start + 1;
}
for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) {
for (n = 0; n < length; n += 8) { //
int64_t pss_corr_ue=0;
......@@ -748,10 +749,10 @@ int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain
}
// computing absolute value of frequency offset
*f_off = ffo_est*frame_parms->subcarrier_spacing;
*f_off = ffo_est*frame_parms->subcarrier_spacing;
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++)
avg[pss_index]/=(length/4);
for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++)
avg[pss_index] /= (length / 4);
*eNB_id = pss_source;
......@@ -776,6 +777,6 @@ int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain
#endif
return(peak_position);
return peak_position;
}
......@@ -511,9 +511,15 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
/* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */
/* sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
for (Nid1 = 0 ; Nid1 < N_ID_1_NUMBER; Nid1++) { // all possible Nid1 values
for (phase=0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS
uint16_t Nid1_start = 0;
uint16_t Nid1_end = N_ID_1_NUMBER;
if (ue->target_Nid_cell != -1) {
Nid1_start = GET_NID1(ue->target_Nid_cell);
Nid1_end = Nid1_start + 1;
}
for (Nid1 = Nid1_start; Nid1 < Nid1_end; Nid1++) { // all possible Nid1 values
for (phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS
metric = 0;
metric_re = 0;
......@@ -523,7 +529,6 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
// This is the inner product using one particular value of each unknown parameter
for (i=0; i < LENGTH_SSS_NR; i++) {
metric_re += d[i]*(((phase_re_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR));
#if 0
......
......@@ -697,7 +697,7 @@ void PainterWidgetGnb::makeConnections(int type)
break;
}
case PlotTypeGnb::CIR: {
newChart = new CIRPlot((complex16 *)p->gNB->pusch_vars[0]->ul_ch_estimates_time[0], frame_parms->ofdm_symbol_size);
newChart = new CIRPlot((complex16 *)p->gNB->pusch_vars[0].ul_ch_estimates_time[0], frame_parms->ofdm_symbol_size);
break;
}
......@@ -705,12 +705,12 @@ void PainterWidgetGnb::makeConnections(int type)
int num_re = frame_parms->N_RB_UL * 12 * frame_parms->symbols_per_slot;
int Qm = 2;
int coded_bits_per_codeword = num_re * Qm;
newChart = new LLRPlot((int16_t *)p->gNB->pusch_vars[0]->llr, coded_bits_per_codeword);
newChart = new LLRPlot((int16_t *)p->gNB->pusch_vars[0].llr, coded_bits_per_codeword);
break;
}
case PlotTypeGnb::puschIQ: {
int num_re = frame_parms->N_RB_UL * 12 * frame_parms->symbols_per_slot;
newChart = new IQPlot((complex16 *)p->gNB->pusch_vars[0]->rxdataF_comp[0], num_re);
newChart = new IQPlot((complex16 *)p->gNB->pusch_vars[0].rxdataF_comp[0], num_re);
break;
}
case PlotTypeGnb::puschSNR: {
......
This diff is collapsed.
This diff is collapsed.
......@@ -400,6 +400,8 @@ typedef struct {
int if_freq_off;
/// \brief Indicator that UE is synchronized to a gNB
int is_synchronized;
/// \brief Target gNB Nid_cell when UE is resynchronizing
int target_Nid_cell;
/// \brief Indicator that UE lost frame synchronization
int lost_sync;
/// Data structure for UE process scheduling
......@@ -440,6 +442,7 @@ typedef struct {
nr_ue_if_module_t *if_inst;
fapi_nr_config_request_t nrUE_config;
nr_synch_request_t synch_request;
NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX];
......
This diff is collapsed.
This diff is collapsed.
......@@ -548,3 +548,11 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config)
memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t));
return 0;
}
void nr_ue_synch_request(nr_synch_request_t *synch_request)
{
fapi_nr_synch_request_t *synch_req = &PHY_vars_UE_g[synch_request->Mod_id][synch_request->CC_id]->synch_request.synch_req;
memcpy(synch_req, &synch_request->synch_req, sizeof(fapi_nr_synch_request_t));
PHY_vars_UE_g[synch_request->Mod_id][synch_request->CC_id]->synch_request.received_synch_request = 1;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment