+
+**TABLE OF CONTENTS**
+
+1. [Scenario](#1-scenario)
+2. [OAI CN5G](#2-oai-cn5g)
+ 1. [OAI CN5G pre-requisites](#21-oai-cn5g-pre-requisites)
+ 2. [OAI CN5G Setup](#22-oai-cn5g-setup)
+ 3. [OAI CN5G Configuration files](#23-oai-cn5g-configuration-files)
+ 4. [SIM Card](#24-sim-card)
+3. [OAI gNB](#3-oai-gnb)
+ 1. [OAI gNB pre-requisites](#31-oai-gnb-pre-requisites)
+ 2. [Build OAI gNB](#32-build-oai-gnb)
+ 3. [N300 Ethernet Tuning](#33-n300-ethernet-tuning)
+4. [Run OAI CN5G and OAI gNB with USRP N300](#4-run-oai-cn5g-and-oai-gnb-with-usrp-n300)
+ 1. [Run OAI CN5G](#41-run-oai-cn5g)
+ 2. [Run OAI gNB](#42-run-oai-gnb)
+5. [Testing with QUECTEL RM500Q](#5-testing-with-quectel-rm500q)
+ 1. [Setup QUECTEL](#51-setup-quectel)
+ 2. [Ping test](#52-ping-test)
+ 3. [Downlink iPerf test](#53-downlink-iperf-test)
+
+
+# 1. Scenario
+In this tutorial we describe how to configure and run a 5G end-to-end setup with OAI CN5G, OAI gNB and COTS UE.
+
+Minimum hardware requirements:
+- Laptop/Desktop/Server for OAI CN5G and OAI gNB
+ - Operating System: [Ubuntu 20.04.4 LTS](https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-desktop-amd64.iso)
+ - CPU: 8 cores x86_64 @ 3.5 GHz
+ - RAM: 32 GB
+- Laptop for UE
+ - Operating System: Microsoft Windows 10 x64
+ - CPU: 4 cores x86_64
+ - RAM: 8 GB
+ - Windows driver for Quectel MUST be equal or higher than version **2.2.4**
+- [USRP N300](https://www.ettus.com/all-products/USRP-N300/): Please identify the network interface(s) on which the N300 is connected.
+- Quectel RM500Q
+ - Module, M.2 to USB adapter, antennas and SIM card
+ - Firmware version of Quectel MUST be equal or higher than **RM500QGLABR11A06M4G**
+
+
+# 2. OAI CN5G
+
+## 2.1 OAI CN5G pre-requisites
+
+```bash
+sudo apt install -y git net-tools putty
+
+sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
+curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
+sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
+sudo apt update
+sudo apt install -y docker docker-ce
+
+# Add your username to the docker group, otherwise you will have to run in sudo mode.
+sudo usermod -a -G docker $(whoami)
+reboot
+
+# https://docs.docker.com/compose/install/
+sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
+sudo chmod +x /usr/local/bin/docker-compose
+```
+
+## 2.2 OAI CN5G Setup
+
+```bash
+# Git oai-cn5g-fed repository
+git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
+
+# Pull docker images
+docker pull oaisoftwarealliance/oai-amf:develop
+docker pull oaisoftwarealliance/oai-nrf:develop
+docker pull oaisoftwarealliance/oai-smf:develop
+docker pull oaisoftwarealliance/oai-udr:develop
+docker pull oaisoftwarealliance/oai-udm:develop
+docker pull oaisoftwarealliance/oai-ausf:develop
+docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
+docker pull oaisoftwarealliance/trf-gen-cn5g:latest
+
+# Tag docker images
+docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
+docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
+docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
+docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
+docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
+docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
+docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
+docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest
+```
+
+## 2.3 OAI CN5G Configuration files
+Download and copy configuration files:
+- Copy [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) to `~/oai-cn5g-fed/docker-compose`
+- Copy [oai_db.sql](tutorial_resources/oai_db.sql) to `~/oai-cn5g-fed/docker-compose/database`
+
+Change permissions on oai_db.sql to prevent mysql permission denied error:
+```bash
+chmod 644 ~/oai-cn5g-fed/docker-compose/database/oai_db.sql
+```
+
+## 2.4 SIM Card
+Program SIM Card with [Open Cells Project](https://open-cells.com/) application [uicc-v2.6](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v2.6.tgz).
+
+```bash
+sudo ./program_uicc --adm 12345678 --imsi 208990000000001 --isdn 00000001 --acc 0001 --key fec86ba6eb707ed08905757b1bb44b8f --opc C42449363BBAD02B66D16BC975D77CC1 -spn "OpenAirInterface" --authenticate
+```
+
+
+# 3. OAI gNB
+
+## 3.1 OAI gNB pre-requisites
+
+### Build UHD from source
+```bash
+sudo apt install -y libboost-all-dev libusb-1.0-0-dev doxygen python3-docutils python3-mako python3-numpy python3-requests python3-ruamel.yaml python3-setuptools cmake build-essential
+
+git clone https://github.com/EttusResearch/uhd.git ~/uhd
+cd ~/uhd
+git checkout v4.0.0.0
+cd host
+mkdir build
+cd build
+cmake ../
+make -j 4
+make test # This step is optional
+sudo make install
+sudo ldconfig
+sudo uhd_images_downloader
+```
+
+## 3.2 Build OAI gNB
+
+```bash
+# Get openairinterface5g source code
+git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
+cd ~/openairinterface5g
+git checkout develop
+
+# Install dependencies in Ubuntu 20.04
+cd ~/openairinterface5g
+source oaienv
+cd cmake_targets
+./build_oai -I
+
+# Build OAI gNB
+cd ~/openairinterface5g
+source oaienv
+cd cmake_targets
+./build_oai -w USRP --nrUE --gNB --build-lib all -c
+```
+
+## 3.3 N300 Ethernet Tuning
+
+Please also refer to the official [USRP Host Performance Tuning Tips and Tricks](https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks) tuning guide.
+
+The following steps are recommended. Please change the network interface(s) as required. Also, you should have 10Gbps interface(s): if you use two cables, you should have the XG interface. Refer to the [N300 Getting Started Guide](https://kb.ettus.com/USRP_N300/N310/N320/N321_Getting_Started_Guide) for more information.
+
+* Use an MTU of 9000: how to change this depends on the network management tool. In the case of Network Manager, this can be done from the GUI.
+* Increase the kernel socket buffer (also done by the USRP driver in OAI):
+ ```
+ sysctl -w net.core.rmem_max=8388608
+ sysctl -w net.core.wmem_max=8388608
+ sysctl -w net.core.rmem_default=65536
+ sysctl -w net.core.wmem_default=65536
+ ```
+* Increase Ethernet Ring Buffers: `sudo ethtool -G rx 4096 tx 4096`
+* Disable hyper-threading in the BIOS
+* Disable KPTI Protections for Spectre/Meltdown for more performance. **This is a security risk.** Add `mitigations=off nosmt` in your grub config and update grub.
+
+# 4. Run OAI CN5G and OAI gNB with USRP N300
+
+## 4.1 Run OAI CN5G
+
+```bash
+cd ~/oai-cn5g-fed/docker-compose
+python3 core-network.py --type start-basic --scenario 1
+```
+
+## 4.2 Run OAI gNB
+
+```bash
+cd ~/openairinterface5g
+source oaienv
+cd cmake_targets/ran_build/build
+sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf --sa --usrp-tx-thread-config 1
+```
+
+
+# 5. Testing with Quectel RM500Q
+
+## 5.1 Setup Quectel
+With [PuTTY](https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe), send the following AT commands to the module using a serial interface (ex: COM2) at 115200 bps:
+```bash
+# MUST be sent at least once everytime there is a firmware upgrade!
+AT+QMBNCFG="Select","ROW_Commercial"
+AT+QMBNCFG="AutoSel",0
+AT+CFUN=1,1
+AT+CGDCONT=1
+AT+CGDCONT=2
+AT+CGDCONT=3
+AT+CGDCONT=1,"IP","oai"
+
+# (Optional, debug only, AT commands) Activate PDP context, retrieve IP address and test with ping
+AT+CGACT=1,1
+AT+CGPADDR=1
+AT+QPING=1,"openairinterface.org"
+```
+
+## 5.2 Ping test
+- UE host
+```bash
+ping 192.168.70.135 -n 1000 -S 12.1.1.2
+```
+- CN5G host
+```bash
+docker exec -it oai-ext-dn ping 12.1.1.2
+```
+
+## 5.3 Downlink iPerf test
+- UE host
+ - Download iPerf for Microsoft Windows from [here](https://iperf.fr/download/windows/iperf-2.0.9-win64.zip).
+ - Extract to Desktop and run with Command Prompt:
+```bash
+cd C:\Users\User\Desktop\iPerf\iperf-2.0.9-win64\iperf-2.0.9-win64
+iperf -s -u -i 1 -B 12.1.1.2
+```
+
+- CN5G host
+```bash
+docker exec -it oai-ext-dn iperf -u -t 86400 -i 1 -fk -B 192.168.70.135 -b 200M -c 12.1.1.2
+```
diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md
index 547fd5a23b..c6a01f278d 100644
--- a/doc/TESTBenches.md
+++ b/doc/TESTBenches.md
@@ -9,19 +9,19 @@
| Machine | IP address | Lockable Resource | Function | Connected devices |
| ------------- | --------------- | --------------------- | ------------------ | ----------------------------------------------------- |
-| asterix | 172.21.16.127 | CI-Asterix-Usage | gNB | 173.21.19.14 |
-| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB, UE (5G) | 172.21.19.13, X300 (192.168.60.2), B200mini (30C51EB) |
+| asterix | 172.21.16.127 | CI-Asterix-Usage | gNB (n78) | 173.21.19.14 |
+| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB (n40, n78), nrUE | 172.21.19.13, X300 (192.168.60.2), B200mini (30C51EB) |
| porcepix | 172.21.16.136 | CI-NSA-MiniBench | Executor, EPC, 5GC | -- |
| nrmodule2 | 172.21.16.139 | CI-NSA-MiniBench | Quectel | Quectel module |
-| nepes | 172.21.16.137 | CI-NSA-MiniBench | gNB | B200mini (30C51D4) |
+| nepes | 172.21.16.137 | CI-NSA-MiniBench | gNB (n78) | B200mini (30C51D4) |
| caracal | 172.21.16.132 | CI-Caracal | gNB/phytest | N300 (192.168.10.2) |
| idefix | 172.21.16.135 | CI-NSA-MiniBench | Quectel | Quectel module |
-| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | TBD | Amarisoft UE simulator |
+| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | nrUE | Amarisoft UE simulator |
| bellatrix | 192.168.117.115 | CI-RAN-VM-Deployment | Executor | -- |
| nano | 192.168.12.62 | CI-Bench-1-Phones | EPC, adb | 2x COTS (adb) |
| hutch | 192.168.12.19 | CI-Bench-1-Phones | eNB (B7) | B200mini (30C5239) |
| starsky | 192.168.12.18 | CI-Bench-1-Phones | eNB (B40) | b200mini (30A3E3C) |
-| carabe | 192.168.12.211 | CI-Bench-2-OAI-Phone | UE 4G (B) | B200mini (30AE8C9) |
+| carabe | 192.168.12.211 | CI-Bench-2-OAI-Phone | UE (B7UE) | B200mini (30AE8C9) |
Note: The available resources, and their current usage, is indicated here:
- [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/):
@@ -40,7 +40,7 @@ Note: The available resources, and their current usage, is indicated here:
### OTA Testbench
-[Proper image to be followed up. TBD: add antennas/circulators]
+**Purpose**: Over-the-air 4G/5G (NSA/SA) tests
Note: obelix and porcepix are both used in the OTA testbench and the 5G
NSA/Faraday Cage testbench!
@@ -89,7 +89,10 @@ Webhook
currently only ping
- [RAN-NSA-B200-Module-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-NSA-B200-Module-LTEBOX-Container/)
- obelix + B200, nepes + B200, idefix + Quectel, porcepix w/ ltebox
- - basic NSA test, known to be instable
+ - basic NSA test
+- [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/)
+ - obelix + B200, nepes + B200, idefix + Quectel, porcepix w/ sabox
+ - basic SA test (40 MHz TDD)
- [RAN-PhySim-Cluster](https://jenkins-oai.eurecom.fr/job/RAN-PhySim-Cluster/)
- asterix (`Asterix-OC-oaicicd-session` resource), tests in OpenShift Cluster
- unitary simulators (`nr_dlsim`, etc.)
diff --git a/doc/testbenches_doc_resources/4g-faraday-bench.pdf b/doc/testbenches_doc_resources/4g-faraday-bench.pdf
index 7e31789e9a..f6f7b078e6 100644
Binary files a/doc/testbenches_doc_resources/4g-faraday-bench.pdf and b/doc/testbenches_doc_resources/4g-faraday-bench.pdf differ
diff --git a/doc/testbenches_doc_resources/4g-faraday-bench.png b/doc/testbenches_doc_resources/4g-faraday-bench.png
index c69065a369..598715a193 100644
Binary files a/doc/testbenches_doc_resources/4g-faraday-bench.png and b/doc/testbenches_doc_resources/4g-faraday-bench.png differ
diff --git a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf
index f6d960c1a2..1b921e6437 100644
Binary files a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf and b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf differ
diff --git a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png
index c677b598e9..006e6ab347 100644
Binary files a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png and b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png differ
diff --git a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex
index 66b52f7f69..a9f12fe3df 100644
--- a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex
+++ b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex
@@ -30,7 +30,7 @@
\draw (obelix) -- (b210o);
\node[above right=0.35cm of faraday.south west] (antn)
{\includegraphics[width=0.3cm]{antenna}};
- \draw (b210n) -| node [pos=0.2, duplexer] {B78} (antn);
+ \draw (b210n) -| node [pos=0.2, duplexer] {n78} (antn);
\node[left=5cm of faraday, label=above:porcepix] (porcepix)
{\includegraphics[width=1.2cm]{server}};
diff --git a/doc/testbenches_doc_resources/5g-ota-bench.pdf b/doc/testbenches_doc_resources/5g-ota-bench.pdf
index e4d4c15e39..121969030e 100644
Binary files a/doc/testbenches_doc_resources/5g-ota-bench.pdf and b/doc/testbenches_doc_resources/5g-ota-bench.pdf differ
diff --git a/doc/testbenches_doc_resources/5g-ota-bench.png b/doc/testbenches_doc_resources/5g-ota-bench.png
index c93de7ec6f..86ae6b2b64 100644
Binary files a/doc/testbenches_doc_resources/5g-ota-bench.png and b/doc/testbenches_doc_resources/5g-ota-bench.png differ
diff --git a/doc/testbenches_doc_resources/5g-ota-bench.tex b/doc/testbenches_doc_resources/5g-ota-bench.tex
index cfd0bda22d..c3a524fb0a 100644
--- a/doc/testbenches_doc_resources/5g-ota-bench.tex
+++ b/doc/testbenches_doc_resources/5g-ota-bench.tex
@@ -21,7 +21,7 @@
edge (porcepix);
\node[right=0.3cm of asterix, label=above:N310] (n310a)
{\includegraphics[width=1.5cm]{n310}} edge (asterix);
- \node[right=.2cm of n310a, duplexer] (b78o) {B78} edge (n310a);
+ \node[right=.2cm of n310a, duplexer] (b78o) {n78} edge (n310a);
\node[below right=-0.1cm and 0.35cm of b78o.east] (anto1)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
@@ -32,20 +32,20 @@
edge (porcepix);
\node[above right=-0.5cm and 0.3cm of obelix, label=above:N310] (n310o)
{\includegraphics[width=1.5cm]{n310}} edge (obelix);
- \node[right=.2cm of n310o, duplexer] (b78o) {B40} edge (n310o);
+ \node[right=.2cm of n310o, duplexer] (b78o) {n40} edge (n310o);
\node[below right=-0.1cm and 0.35cm of b78o.east] (anto1)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[below right=-0.5cm and 0.3cm of obelix, label=above:X310] (x310o)
{\includegraphics[width=1.5cm]{x310}} edge (obelix);
- \node[right=.2cm of x310o, duplexer] (b78o) {B78} edge (x310o);
+ \node[right=.2cm of x310o, duplexer] (b78o) {n78} edge (x310o);
\node[below right=-0.1cm and 0.35cm of b78o.east] (anto1)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
- \node[right=5.0cm of n310o, label=above:RM500Q-GL] (quectel)
+ \node[above right=-1.3cm and 5.0cm of n310a.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,5 +59,10 @@
{\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}
diff --git a/doc/testing_gnb_w_cots_ue_resources/gnb.conf b/doc/testing_gnb_w_cots_ue_resources/gnb.conf
index c96d207445..206e1b4f02 100755
--- a/doc/testing_gnb_w_cots_ue_resources/gnb.conf
+++ b/doc/testing_gnb_w_cots_ue_resources/gnb.conf
@@ -21,8 +21,6 @@ gNBs =
////////// Physical parameters:
- ssb_SubcarrierOffset = 31; //0;
- pdsch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/doc/tutorial_resources/docker-compose-basic-nrf.yaml b/doc/tutorial_resources/docker-compose-basic-nrf.yaml
new file mode 100644
index 0000000000..cd1e957ad8
--- /dev/null
+++ b/doc/tutorial_resources/docker-compose-basic-nrf.yaml
@@ -0,0 +1,360 @@
+version: '3.8'
+services:
+ mysql:
+ container_name: "mysql"
+ image: mysql:5.7
+ volumes:
+ - ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
+ - ./healthscripts/mysql-healthcheck2.sh:/tmp/mysql-healthcheck.sh
+ environment:
+ - TZ=Europe/Paris
+ - MYSQL_DATABASE=oai_db
+ - MYSQL_USER=test
+ - MYSQL_PASSWORD=test
+ - MYSQL_ROOT_PASSWORD=linux
+ healthcheck:
+ test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ networks:
+ public_net:
+ ipv4_address: 192.168.70.131
+ oai-udr:
+ container_name: "oai-udr"
+ image: oai-udr:develop
+ environment:
+ - TZ=Europe/Paris
+ - INSTANCE=0
+ - PID_DIRECTORY=/var/run
+ - UDR_NAME=OAI_UDR
+ - UDR_INTERFACE_NAME_FOR_NUDR=eth0
+ - UDR_INTERFACE_PORT_FOR_NUDR=80
+ - UDR_INTERFACE_HTTP2_PORT_FOR_NUDR=8080
+ - USE_HTTP2=no
+ - UDR_API_VERSION=v1
+ - MYSQL_IPV4_ADDRESS=192.168.70.131
+ - MYSQL_USER=test
+ - MYSQL_PASS=test
+ - DB_CONNECTION_TIMEOUT=300 # Reset the connection to the DB after expiring the timeout (in second) currently can't be changed
+ - MYSQL_DB=oai_db
+ - WAIT_MYSQL=120
+ - USE_FQDN_DNS=yes
+ - REGISTER_NRF=yes
+ - NRF_IPV4_ADDRESS=192.168.70.130
+ - NRF_PORT=80
+ - NRF_API_VERSION=v1
+ - NRF_FQDN=oai-nrf
+ depends_on:
+ - mysql
+ - oai-nrf
+ networks:
+ public_net:
+ ipv4_address: 192.168.70.136
+ volumes:
+ - ./healthscripts/udr-healthcheck.sh:/openair-udr/bin/udr-healthcheck.sh
+ healthcheck:
+ test: /bin/bash -c "/openair-udr/bin/udr-healthcheck.sh"
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ oai-udm:
+ container_name: "oai-udm"
+ image: oai-udm:develop
+ environment:
+ - TZ=Europe/Paris
+ - INSTANCE=0
+ - PID_DIRECTORY=/var/run
+ - UDM_NAME=OAI_UDM
+ - SBI_IF_NAME=eth0
+ - SBI_PORT=80
+ - SBI_HTTP2_PORT=8080
+ - USE_HTTP2=no
+ - UDM_VERSION_NB=v1
+ - USE_FQDN_DNS=yes
+ - UDR_IP_ADDRESS=192.168.70.136
+ - UDR_PORT=80
+ - UDR_VERSION_NB=v1
+ - UDR_FQDN=oai-udr
+ - REGISTER_NRF=yes
+ - NRF_IPV4_ADDRESS=192.168.70.130
+ - NRF_PORT=80
+ - NRF_API_VERSION=v1
+ - NRF_FQDN=oai-nrf
+ depends_on:
+ - oai-udr
+ networks:
+ public_net:
+ ipv4_address: 192.168.70.137
+ volumes:
+ - ./healthscripts/udm-healthcheck.sh:/openair-udm/bin/udm-healthcheck.sh
+ healthcheck:
+ test: /bin/bash -c "/openair-udm/bin/udm-healthcheck.sh"
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ oai-ausf:
+ container_name: "oai-ausf"
+ image: oai-ausf:develop
+ environment:
+ - TZ=Europe/Paris
+ - INSTANCE_ID=0
+ - PID_DIR=/var/run
+ - AUSF_NAME=OAI_AUSF
+ - SBI_IF_NAME=eth0
+ - SBI_PORT=80
+ - USE_HTTP2
+ - SBI_HTTP2_PORT
+ - USE_FQDN_DNS=yes
+ - UDM_IP_ADDRESS=192.168.70.137
+ - UDM_PORT=80
+ - UDM_VERSION_NB=v1
+ - UDM_FQDN=oai-udm
+ - REGISTER_NRF=yes
+ - NRF_IPV4_ADDRESS=192.168.70.130
+ - NRF_PORT=80
+ - NRF_API_VERSION=v1
+ - NRF_FQDN=oai-nrf
+ depends_on:
+ - oai-udm
+ networks:
+ public_net:
+ ipv4_address: 192.168.70.138
+ volumes:
+ - ./healthscripts/ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh
+ healthcheck:
+ test: /bin/bash -c "/openair-ausf/bin/ausf-healthcheck.sh"
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ oai-nrf:
+ container_name: "oai-nrf"
+ image: oai-nrf:develop
+ environment:
+ - TZ=Europe/Paris
+ - NRF_INTERFACE_NAME_FOR_SBI=eth0
+ - NRF_INTERFACE_PORT_FOR_SBI=80
+ - NRF_INTERFACE_HTTP2_PORT_FOR_SBI=8080
+ - NRF_API_VERSION=v1
+ - INSTANCE=0
+ - PID_DIRECTORY=/var/run
+ networks:
+ public_net:
+ ipv4_address: 192.168.70.130
+ volumes:
+ - ./healthscripts/nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh
+ healthcheck:
+ test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh"
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ oai-amf:
+ container_name: "oai-amf"
+ image: oai-amf:develop
+ environment:
+ - TZ=Europe/paris
+ - INSTANCE=0
+ - PID_DIRECTORY=/var/run
+ - MCC=208
+ - MNC=99
+ - REGION_ID=128
+ - AMF_SET_ID=1
+ - SERVED_GUAMI_MCC_0=208
+ - SERVED_GUAMI_MNC_0=99
+ - SERVED_GUAMI_REGION_ID_0=128
+ - SERVED_GUAMI_AMF_SET_ID_0=1
+ - SERVED_GUAMI_MCC_1=460
+ - SERVED_GUAMI_MNC_1=11
+ - SERVED_GUAMI_REGION_ID_1=10
+ - SERVED_GUAMI_AMF_SET_ID_1=1
+ - PLMN_SUPPORT_MCC=208
+ - PLMN_SUPPORT_MNC=99
+ - PLMN_SUPPORT_TAC=0x0001
+ - SST_0=1
+ - SD_0=0x1
+ - AMF_INTERFACE_NAME_FOR_NGAP=eth0
+ - AMF_INTERFACE_NAME_FOR_N11=eth0
+ - SMF_INSTANCE_ID_0=1
+ - SMF_FQDN_0=oai-smf
+ - SMF_IPV4_ADDR_0=192.168.70.133
+ - SMF_HTTP_VERSION_0=v1
+ - SELECTED_0=true
+ - SMF_INSTANCE_ID_1=2
+ - SMF_FQDN_1=oai-smf
+ - SMF_IPV4_ADDR_1=0.0.0.0
+ - SMF_HTTP_VERSION_1=v1
+ - SELECTED_1=false
+ - MYSQL_SERVER=192.168.70.131
+ - MYSQL_USER=root
+ - MYSQL_PASS=linux
+ - MYSQL_DB=oai_db
+ - OPERATOR_KEY=1006020f0a478bf6b699f15c062e42b3
+ - NRF_IPV4_ADDRESS=192.168.70.130
+ - NRF_PORT=80
+ - EXTERNAL_NRF=no
+ - NF_REGISTRATION=yes
+ - SMF_SELECTION=yes
+ - USE_FQDN_DNS=yes
+ - EXTERNAL_AUSF=yes
+ - EXTERNAL_UDM=no
+ - EXTERNAL_NSSF=no
+ - USE_HTTP2=no
+ - NRF_API_VERSION=v1
+ - NRF_FQDN=oai-nrf
+ - AUSF_IPV4_ADDRESS=192.168.70.138
+ - AUSF_PORT=80
+ - AUSF_API_VERSION=v1
+ - AUSF_FQDN=oai-ausf
+ - UDM_IPV4_ADDRESS=192.168.70.137
+ - UDM_PORT=80
+ - UDM_API_VERSION=v2
+ - UDM_FQDN=oai-udm
+ depends_on:
+ - mysql
+ - oai-nrf
+ - oai-ausf
+ volumes:
+ - ./healthscripts/amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh
+ healthcheck:
+ test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh"
+ interval: 10s
+ timeout: 15s
+ retries: 5
+ networks:
+ public_net:
+ ipv4_address: 192.168.70.132
+ oai-smf:
+ container_name: "oai-smf"
+ image: oai-smf:develop
+ environment:
+ - TZ=Europe/Paris
+ - INSTANCE=0
+ - PID_DIRECTORY=/var/run
+ - SMF_INTERFACE_NAME_FOR_N4=eth0
+ - SMF_INTERFACE_NAME_FOR_SBI=eth0
+ - SMF_INTERFACE_PORT_FOR_SBI=80
+ - SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
+ - SMF_API_VERSION=v1
+ - DEFAULT_DNS_IPV4_ADDRESS=8.8.8.8
+ - DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
+ - AMF_IPV4_ADDRESS=192.168.70.132
+ - AMF_PORT=80
+ - AMF_API_VERSION=v1
+ - AMF_FQDN=oai-amf
+ - UDM_IPV4_ADDRESS=192.168.70.137
+ - UDM_PORT=80
+ - UDM_API_VERSION=v2
+ - UDM_FQDN=oai-udm
+ - UPF_IPV4_ADDRESS=192.168.70.134
+ - UPF_FQDN_0=oai-spgwu
+ - NRF_IPV4_ADDRESS=192.168.70.130
+ - NRF_PORT=80
+ - NRF_API_VERSION=v1
+ - USE_LOCAL_SUBSCRIPTION_INFO=yes #Set to yes if SMF uses local subscription information instead of from an UDM
+ - USE_NETWORK_INSTANCE=no #Set yes if network instance is to be used for given UPF
+ - NRF_FQDN=oai-nrf
+ - REGISTER_NRF=yes
+ - DISCOVER_UPF=yes
+ - USE_FQDN_DNS=yes
+ - HTTP_VERSION=1 # Default: 1
+ - UE_MTU=1500
+ - DNN_NI0=oai
+ - TYPE0=IPv4
+ - DNN_RANGE0=12.1.1.2 - 12.1.1.253
+ - NSSAI_SST0=1
+ - NSSAI_SD0=0x1
+ - SESSION_AMBR_UL0=1000Mbps
+ - SESSION_AMBR_DL0=1000Mbps
+ - DEFAULT_CSCF_IPV4_ADDRESS=127.0.0.1 # only needed when ims is being used
+ - ENABLE_USAGE_REPORTING=no # Set yes if UE USAGE REPORTING is to be done at UPF
+ depends_on:
+ - oai-nrf
+ - oai-amf
+ volumes:
+ - ./healthscripts/smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
+ healthcheck:
+ test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ networks:
+ public_net:
+ ipv4_address: 192.168.70.133
+ oai-spgwu:
+ container_name: "oai-spgwu"
+ image: oai-spgwu-tiny:develop
+ environment:
+ - TZ=Europe/Paris
+ - PID_DIRECTORY=/var/run
+ - SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0
+ - SGW_INTERFACE_NAME_FOR_SX=eth0
+ - PGW_INTERFACE_NAME_FOR_SGI=eth0
+ - NETWORK_UE_NAT_OPTION=yes
+ - NETWORK_UE_IP=12.1.1.0/24
+ - SPGWC0_IP_ADDRESS=192.168.70.133
+ - BYPASS_UL_PFCP_RULES=no
+ - MCC=208
+ - MNC=99
+ - MNC03=099
+ - TAC=1
+ - GW_ID=1
+ - THREAD_S1U_PRIO=80
+ - S1U_THREADS=8
+ - THREAD_SX_PRIO=81
+ - SX_THREADS=1
+ - THREAD_SGI_PRIO=80
+ - SGI_THREADS=8
+ - REALM=openairinterface.org
+ - ENABLE_5G_FEATURES=yes
+ - REGISTER_NRF=yes
+ - USE_FQDN_NRF=yes
+ - UPF_FQDN_5G=oai-spgwu
+ - NRF_IPV4_ADDRESS=192.168.70.130
+ - NRF_PORT=80
+ - NRF_API_VERSION=v1
+ - NRF_FQDN=oai-nrf
+ - NSSAI_SST_0=1
+ - NSSAI_SD_0=0x1
+ - DNN_0=oai
+ depends_on:
+ - oai-nrf
+ - oai-smf
+ cap_add:
+ - NET_ADMIN
+ - SYS_ADMIN
+ cap_drop:
+ - ALL
+ privileged: true
+ volumes:
+ - ./healthscripts/spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh
+ healthcheck:
+ test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh"
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ networks:
+ public_net:
+ ipv4_address: 192.168.70.134
+ oai-ext-dn:
+ image: trf-gen-cn5g:latest
+ privileged: true
+ container_name: oai-ext-dn
+ entrypoint: /bin/bash -c \
+ "ip route add 12.1.1.0/24 via 192.168.70.134 dev eth0; sleep infinity"
+ depends_on:
+ - oai-spgwu
+ networks:
+ public_net:
+ ipv4_address: 192.168.70.135
+networks:
+ # public_net:
+ # external:
+ # name: demo-oai-public-net
+ public_net:
+ driver: bridge
+ name: demo-oai-public-net
+ ipam:
+ config:
+ - subnet: 192.168.70.128/26
+ driver_opts:
+ com.docker.network.bridge.name: "demo-oai"
diff --git a/doc/tutorial_resources/oai_db.sql b/doc/tutorial_resources/oai_db.sql
new file mode 100644
index 0000000000..fb8f4b20ed
--- /dev/null
+++ b/doc/tutorial_resources/oai_db.sql
@@ -0,0 +1,328 @@
+-- phpMyAdmin SQL Dump
+-- version 5.1.0
+-- https://www.phpmyadmin.net/
+--
+-- Host: 172.16.200.10:3306
+-- Generation Time: Mar 22, 2021 at 10:31 AM
+-- Server version: 5.7.33
+-- PHP Version: 7.4.15
+
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+START TRANSACTION;
+SET time_zone = "+00:00";
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+
+--
+-- Database: `oai_db`
+--
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `AccessAndMobilitySubscriptionData`
+--
+
+CREATE TABLE `AccessAndMobilitySubscriptionData` (
+ `ueid` varchar(15) NOT NULL,
+ `servingPlmnid` varchar(15) NOT NULL,
+ `supportedFeatures` varchar(50) DEFAULT NULL,
+ `gpsis` json DEFAULT NULL,
+ `internalGroupIds` json DEFAULT NULL,
+ `sharedVnGroupDataIds` json DEFAULT NULL,
+ `subscribedUeAmbr` json DEFAULT NULL,
+ `nssai` json DEFAULT NULL,
+ `ratRestrictions` json DEFAULT NULL,
+ `forbiddenAreas` json DEFAULT NULL,
+ `serviceAreaRestriction` json DEFAULT NULL,
+ `coreNetworkTypeRestrictions` json DEFAULT NULL,
+ `rfspIndex` int(10) DEFAULT NULL,
+ `subsRegTimer` int(10) DEFAULT NULL,
+ `ueUsageType` int(10) DEFAULT NULL,
+ `mpsPriority` tinyint(1) DEFAULT NULL,
+ `mcsPriority` tinyint(1) DEFAULT NULL,
+ `activeTime` int(10) DEFAULT NULL,
+ `sorInfo` json DEFAULT NULL,
+ `sorInfoExpectInd` tinyint(1) DEFAULT NULL,
+ `sorafRetrieval` tinyint(1) DEFAULT NULL,
+ `sorUpdateIndicatorList` json DEFAULT NULL,
+ `upuInfo` json DEFAULT NULL,
+ `micoAllowed` tinyint(1) DEFAULT NULL,
+ `sharedAmDataIds` json DEFAULT NULL,
+ `odbPacketServices` json DEFAULT NULL,
+ `serviceGapTime` int(10) DEFAULT NULL,
+ `mdtUserConsent` json DEFAULT NULL,
+ `mdtConfiguration` json DEFAULT NULL,
+ `traceData` json DEFAULT NULL,
+ `cagData` json DEFAULT NULL,
+ `stnSr` varchar(50) DEFAULT NULL,
+ `cMsisdn` varchar(50) DEFAULT NULL,
+ `nbIoTUePriority` int(10) DEFAULT NULL,
+ `nssaiInclusionAllowed` tinyint(1) DEFAULT NULL,
+ `rgWirelineCharacteristics` varchar(50) DEFAULT NULL,
+ `ecRestrictionDataWb` json DEFAULT NULL,
+ `ecRestrictionDataNb` tinyint(1) DEFAULT NULL,
+ `expectedUeBehaviourList` json DEFAULT NULL,
+ `primaryRatRestrictions` json DEFAULT NULL,
+ `secondaryRatRestrictions` json DEFAULT NULL,
+ `edrxParametersList` json DEFAULT NULL,
+ `ptwParametersList` json DEFAULT NULL,
+ `iabOperationAllowed` tinyint(1) DEFAULT NULL,
+ `wirelineForbiddenAreas` json DEFAULT NULL,
+ `wirelineServiceAreaRestriction` json DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `Amf3GppAccessRegistration`
+--
+
+CREATE TABLE `Amf3GppAccessRegistration` (
+ `ueid` varchar(15) NOT NULL,
+ `amfInstanceId` varchar(50) NOT NULL,
+ `supportedFeatures` varchar(50) DEFAULT NULL,
+ `purgeFlag` tinyint(1) DEFAULT NULL,
+ `pei` varchar(50) DEFAULT NULL,
+ `imsVoPs` json DEFAULT NULL,
+ `deregCallbackUri` varchar(50) NOT NULL,
+ `amfServiceNameDereg` json DEFAULT NULL,
+ `pcscfRestorationCallbackUri` varchar(50) DEFAULT NULL,
+ `amfServiceNamePcscfRest` json DEFAULT NULL,
+ `initialRegistrationInd` tinyint(1) DEFAULT NULL,
+ `guami` json NOT NULL,
+ `backupAmfInfo` json DEFAULT NULL,
+ `drFlag` tinyint(1) DEFAULT NULL,
+ `ratType` json NOT NULL,
+ `urrpIndicator` tinyint(1) DEFAULT NULL,
+ `amfEeSubscriptionId` varchar(50) DEFAULT NULL,
+ `epsInterworkingInfo` json DEFAULT NULL,
+ `ueSrvccCapability` tinyint(1) DEFAULT NULL,
+ `registrationTime` varchar(50) DEFAULT NULL,
+ `vgmlcAddress` json DEFAULT NULL,
+ `contextInfo` json DEFAULT NULL,
+ `noEeSubscriptionInd` tinyint(1) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `AuthenticationStatus`
+--
+
+CREATE TABLE `AuthenticationStatus` (
+ `ueid` varchar(20) NOT NULL,
+ `nfInstanceId` varchar(50) NOT NULL,
+ `success` tinyint(1) NOT NULL,
+ `timeStamp` varchar(50) NOT NULL,
+ `authType` varchar(25) NOT NULL,
+ `servingNetworkName` varchar(50) NOT NULL,
+ `authRemovalInd` tinyint(1) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `AuthenticationSubscription`
+--
+
+CREATE TABLE `AuthenticationSubscription` (
+ `ueid` varchar(20) NOT NULL,
+ `authenticationMethod` varchar(25) NOT NULL,
+ `encPermanentKey` varchar(50) DEFAULT NULL,
+ `protectionParameterId` varchar(50) DEFAULT NULL,
+ `sequenceNumber` json DEFAULT NULL,
+ `authenticationManagementField` varchar(50) DEFAULT NULL,
+ `algorithmId` varchar(50) DEFAULT NULL,
+ `encOpcKey` varchar(50) DEFAULT NULL,
+ `encTopcKey` varchar(50) DEFAULT NULL,
+ `vectorGenerationInHss` tinyint(1) DEFAULT NULL,
+ `n5gcAuthMethod` varchar(15) DEFAULT NULL,
+ `rgAuthenticationInd` tinyint(1) DEFAULT NULL,
+ `supi` varchar(20) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Dumping data for table `AuthenticationSubscription`
+--
+
+INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
+ ('2089900007487', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '2089900007487');
+INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
+ ('208990000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000001');
+INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
+ ('208990000000002', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000002');
+INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
+ ('208990000000003', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000003');
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `SdmSubscriptions`
+--
+
+CREATE TABLE `SdmSubscriptions` (
+ `ueid` varchar(15) NOT NULL,
+ `subsId` int(10) UNSIGNED NOT NULL,
+ `nfInstanceId` varchar(50) NOT NULL,
+ `implicitUnsubscribe` tinyint(1) DEFAULT NULL,
+ `expires` varchar(50) DEFAULT NULL,
+ `callbackReference` varchar(50) NOT NULL,
+ `amfServiceName` json DEFAULT NULL,
+ `monitoredResourceUris` json NOT NULL,
+ `singleNssai` json DEFAULT NULL,
+ `dnn` varchar(50) DEFAULT NULL,
+ `subscriptionId` varchar(50) DEFAULT NULL,
+ `plmnId` json DEFAULT NULL,
+ `immediateReport` tinyint(1) DEFAULT NULL,
+ `report` json DEFAULT NULL,
+ `supportedFeatures` varchar(50) DEFAULT NULL,
+ `contextInfo` json DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `SessionManagementSubscriptionData`
+--
+
+CREATE TABLE `SessionManagementSubscriptionData` (
+ `ueid` varchar(15) NOT NULL,
+ `servingPlmnid` varchar(15) NOT NULL,
+ `singleNssai` json NOT NULL,
+ `dnnConfigurations` json DEFAULT NULL,
+ `internalGroupIds` json DEFAULT NULL,
+ `sharedVnGroupDataIds` json DEFAULT NULL,
+ `sharedDnnConfigurationsId` varchar(50) DEFAULT NULL,
+ `odbPacketServices` json DEFAULT NULL,
+ `traceData` json DEFAULT NULL,
+ `sharedTraceDataId` varchar(50) DEFAULT NULL,
+ `expectedUeBehavioursList` json DEFAULT NULL,
+ `suggestedPacketNumDlList` json DEFAULT NULL,
+ `3gppChargingCharacteristics` varchar(50) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Dumping data for table `SessionManagementSubscriptionData`
+--
+
+INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
+ ('2089900007487', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.2\"}]}}');
+INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
+ ('208990000000001', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.2\"}]}}');
+INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
+ ('208990000000002', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.3\"}]}}');
+INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
+ ('208990000000003', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.4\"}]}}');
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `SmfRegistrations`
+--
+
+CREATE TABLE `SmfRegistrations` (
+ `ueid` varchar(15) NOT NULL,
+ `subpduSessionId` int(10) NOT NULL,
+ `smfInstanceId` varchar(50) NOT NULL,
+ `smfSetId` varchar(50) DEFAULT NULL,
+ `supportedFeatures` varchar(50) DEFAULT NULL,
+ `pduSessionId` int(10) NOT NULL,
+ `singleNssai` json NOT NULL,
+ `dnn` varchar(50) DEFAULT NULL,
+ `emergencyServices` tinyint(1) DEFAULT NULL,
+ `pcscfRestorationCallbackUri` varchar(50) DEFAULT NULL,
+ `plmnId` json NOT NULL,
+ `pgwFqdn` varchar(50) DEFAULT NULL,
+ `epdgInd` tinyint(1) DEFAULT NULL,
+ `deregCallbackUri` varchar(50) DEFAULT NULL,
+ `registrationReason` json DEFAULT NULL,
+ `registrationTime` varchar(50) DEFAULT NULL,
+ `contextInfo` json DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `SmfSelectionSubscriptionData`
+--
+
+CREATE TABLE `SmfSelectionSubscriptionData` (
+ `ueid` varchar(15) NOT NULL,
+ `servingPlmnid` varchar(15) NOT NULL,
+ `supportedFeatures` varchar(50) DEFAULT NULL,
+ `subscribedSnssaiInfos` json DEFAULT NULL,
+ `sharedSnssaiInfosId` varchar(50) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Indexes for dumped tables
+--
+
+--
+-- Indexes for table `AccessAndMobilitySubscriptionData`
+--
+ALTER TABLE `AccessAndMobilitySubscriptionData`
+ ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE;
+
+--
+-- Indexes for table `Amf3GppAccessRegistration`
+--
+ALTER TABLE `Amf3GppAccessRegistration`
+ ADD PRIMARY KEY (`ueid`);
+
+--
+-- Indexes for table `AuthenticationStatus`
+--
+ALTER TABLE `AuthenticationStatus`
+ ADD PRIMARY KEY (`ueid`);
+
+--
+-- Indexes for table `AuthenticationSubscription`
+--
+ALTER TABLE `AuthenticationSubscription`
+ ADD PRIMARY KEY (`ueid`);
+
+--
+-- Indexes for table `SdmSubscriptions`
+--
+ALTER TABLE `SdmSubscriptions`
+ ADD PRIMARY KEY (`subsId`,`ueid`) USING BTREE;
+
+--
+-- Indexes for table `SessionManagementSubscriptionData`
+--
+ALTER TABLE `SessionManagementSubscriptionData`
+ ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE;
+
+--
+-- Indexes for table `SmfRegistrations`
+--
+ALTER TABLE `SmfRegistrations`
+ ADD PRIMARY KEY (`ueid`,`subpduSessionId`) USING BTREE;
+
+--
+-- Indexes for table `SmfSelectionSubscriptionData`
+--
+ALTER TABLE `SmfSelectionSubscriptionData`
+ ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE;
+
+--
+-- AUTO_INCREMENT for dumped tables
+--
+
+--
+-- AUTO_INCREMENT for table `SdmSubscriptions`
+--
+ALTER TABLE `SdmSubscriptions`
+ MODIFY `subsId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
+COMMIT;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+
diff --git a/docker/Dockerfile.build.rhel8.2 b/docker/Dockerfile.build.rhel8.2
index 22486c5e68..2664096a9b 100644
--- a/docker/Dockerfile.build.rhel8.2
+++ b/docker/Dockerfile.build.rhel8.2
@@ -35,4 +35,4 @@ COPY . .
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
- ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci
+ ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512
diff --git a/docker/Dockerfile.build.ubuntu18 b/docker/Dockerfile.build.ubuntu18
index 3ba1e41442..7809d56216 100644
--- a/docker/Dockerfile.build.ubuntu18
+++ b/docker/Dockerfile.build.ubuntu18
@@ -35,4 +35,4 @@ COPY . .
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
- ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci
+ ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512
diff --git a/docker/Dockerfile.phySim.rhel8.2 b/docker/Dockerfile.phySim.rhel8.2
index 2627a9eafd..b4eb9a1eeb 100644
--- a/docker/Dockerfile.phySim.rhel8.2
+++ b/docker/Dockerfile.phySim.rhel8.2
@@ -38,7 +38,7 @@ RUN yum install -y libasan
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
- ./build_oai --phy_simulators --ninja --verbose-ci --sanitize-address
+ ./build_oai --phy_simulators --ninja --verbose-ci --sanitize-address --noavx512
#start from scratch for target executable
FROM registry.access.redhat.com/ubi8/ubi:latest as oai-physim
diff --git a/docker/scripts/generateTemplate.py b/docker/scripts/generateTemplate.py
index 850bb535a5..ec8f32ec6e 100644
--- a/docker/scripts/generateTemplate.py
+++ b/docker/scripts/generateTemplate.py
@@ -60,6 +60,7 @@ def main():
"rcc.band40.tm1.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
"gnb.band78.tm1.fr1.106PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
"gnb.band78.sa.fr1.106PRB.usrpn310.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+ "gnb.sa.band78.fr1.106PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
"gnb.sa.band66.fr1.106PRB.usrpn300.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
"gNB_SA_CU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
"gNB_SA_DU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh
index dd6256609c..ac0e0d4c88 100755
--- a/docker/scripts/gnb_entrypoint.sh
+++ b/docker/scripts/gnb_entrypoint.sh
@@ -10,6 +10,7 @@ THREAD_PARALLEL_CONFIG=${THREAD_PARALLEL_CONFIG:-PARALLEL_SINGLE_THREAD}
if [[ -v USE_NSA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.nsa.tdd.conf $PREFIX/etc/gnb.conf; fi
if [[ -v USE_SA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb.conf; fi
+if [[ -v USE_SA_TDD_MONO_B2XX ]]; then cp $PREFIX/etc/gnb.sa.tdd.b2xx.conf $PREFIX/etc/gnb.conf; fi
if [[ -v USE_SA_FDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.fdd.conf $PREFIX/etc/gnb.conf; fi
if [[ -v USE_SA_CU ]]; then cp $PREFIX/etc/gnb.sa.cu.conf $PREFIX/etc/gnb.conf; fi
if [[ -v USE_SA_TDD_CU ]]; then cp $PREFIX/etc/gnb.sa.du.tdd.conf $PREFIX/etc/gnb.conf; fi
diff --git a/docker/scripts/gnb_parameters.yaml b/docker/scripts/gnb_parameters.yaml
index d5942f2c9b..420559ff3f 100644
--- a/docker/scripts/gnb_parameters.yaml
+++ b/docker/scripts/gnb_parameters.yaml
@@ -94,6 +94,36 @@
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
+ - filePrefix: gnb.sa.band78.fr1.106PRB.usrpb210.conf
+ outputfilename: "gnb.sa.tdd.b2xx.conf"
+ config:
+ - key: Active_gNBs
+ env: "@GNB_NAME@"
+ - key: gNB_name
+ env: "@GNB_NAME@"
+ - key: mcc
+ env: "@MCC@"
+ - key: mnc
+ env: "@MNC@"
+ - key: mnc_length
+ env: "@MNC_LENGTH@"
+ - key: tracking_area_code
+ env: "@TAC@"
+ - key: sst
+ env: "@NSSAI_SST@"
+ - key: ipv4
+ env: "@AMF_IP_ADDRESS@"
+ - key: GNB_INTERFACE_NAME_FOR_NG_AMF
+ env: "@GNB_NGA_IF_NAME@"
+ - key: GNB_IPV4_ADDRESS_FOR_NG_AMF
+ env: "@GNB_NGA_IP_ADDRESS@"
+ - key: GNB_INTERFACE_NAME_FOR_NGU
+ env: "@GNB_NGU_IF_NAME@"
+ - key: GNB_IPV4_ADDRESS_FOR_NGU
+ env: "@GNB_NGU_IP_ADDRESS@"
+ - key: parallel_config
+ env: "@THREAD_PARALLEL_CONFIG@"
+
- filePrefix: gnb.sa.band66.fr1.106PRB.usrpn300.conf
outputfilename: "gnb.sa.fdd.conf"
config:
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 8ea7f16712..bc3dccf4fa 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -304,32 +304,36 @@ void rx_func(void *param) {
);
#endif
}
-static void dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output) {
- int stroff = 0;
- stroff += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output);
- stroff += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output+stroff);
- stroff += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output+stroff);
- stroff += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output+stroff);
- stroff += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output+stroff);
- stroff += print_meas_log(&gNB->ulsch_decoding_stats, "PUSCH decoding", NULL, NULL, output+stroff);
- stroff += print_meas_log(&gNB->schedule_response_stats, "Schedule Response",NULL,NULL, output+stroff);
- if (ru->feprx) stroff += print_meas_log(&ru->ofdm_demod_stats,"feprx",NULL,NULL, output+stroff);
+static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) {
+ const char *begin = output;
+ const char *end = output + outputlen;
+ output += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output, end - output);
+ output += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output, end - output);
+ output += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output, end - output);
+ output += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output, end - output);
+ output += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output, end - output);
+ output += print_meas_log(&gNB->ulsch_decoding_stats, "PUSCH decoding", NULL, NULL, output, end - output);
+ output += print_meas_log(&gNB->schedule_response_stats, "Schedule Response", NULL, NULL, output, end - output);
+ if (ru->feprx)
+ output += print_meas_log(&ru->ofdm_demod_stats, "feprx", NULL, NULL, output, end - output);
if (ru->feptx_ofdm) {
- stroff += print_meas_log(&ru->precoding_stats,"feptx_prec",NULL,NULL, output+stroff);
- stroff += print_meas_log(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL, output+stroff);
- stroff += print_meas_log(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL, output+stroff);
- stroff += print_meas_log(&ru->ofdm_total_stats,"feptx_total",NULL,NULL, output+stroff);
+ output += print_meas_log(&ru->precoding_stats,"feptx_prec",NULL,NULL, output, end - output);
+ output += print_meas_log(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL, output, end - output);
+ output += print_meas_log(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL, output, end - output);
+ output += print_meas_log(&ru->ofdm_total_stats,"feptx_total",NULL,NULL, output, end - output);
}
- if (ru->fh_north_asynch_in) stroff += print_meas_log(&ru->rx_fhaul,"rx_fhaul",NULL,NULL, output+stroff);
+ if (ru->fh_north_asynch_in)
+ output += print_meas_log(&ru->rx_fhaul,"rx_fhaul",NULL,NULL, output, end - output);
- stroff += print_meas_log(&ru->tx_fhaul,"tx_fhaul",NULL,NULL, output+stroff);
+ output += print_meas_log(&ru->tx_fhaul,"tx_fhaul",NULL,NULL, output, end - output);
if (ru->fh_north_out) {
- stroff += print_meas_log(&ru->compression,"compression",NULL,NULL, output+stroff);
- stroff += print_meas_log(&ru->transport,"transport",NULL,NULL, output+stroff);
+ output += print_meas_log(&ru->compression,"compression",NULL,NULL, output, end - output);
+ output += print_meas_log(&ru->transport,"transport",NULL,NULL, output, end - output);
}
+ return output - begin;
}
void *nrL1_stats_thread(void *param) {
@@ -355,7 +359,7 @@ void *nrL1_stats_thread(void *param) {
dump_nr_I0_stats(fd,gNB);
dump_pdsch_stats(fd,gNB);
dump_pusch_stats(fd,gNB);
- dump_L1_meas_stats(gNB, ru, output);
+ dump_L1_meas_stats(gNB, ru, output, L1STATSSTRLEN);
fprintf(fd,"%s\n",output);
fflush(fd);
fseek(fd,0,SEEK_SET);
@@ -380,7 +384,7 @@ void *tx_reorder_thread(void* param) {
if (resL1Reserve) {
resL1=resL1Reserve;
if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) {
- LOG_E(PHY,"order mistake");
+ LOG_E(PHY,"order mistake\n");
resL1Reserve=NULL;
resL1 = pullTpool(gNB->L1_tx_out, gNB->threadPool);
}
@@ -462,7 +466,7 @@ void init_gNB_Tpool(int inst) {
pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); // to unblock the process in the beginning
}
- if (!get_softmodem_params()->emulate_l1)
+ if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT))
threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW);
threadCreate(&proc->pthread_tx_reorder, tx_reorder_thread, (void *)gNB, "thread_tx_reorder", -1, OAI_PRIORITY_RT_MAX);
@@ -600,7 +604,8 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/
gNB->prach_energy_counter = 0;
- gNB->prb_interpolation = get_softmodem_params()->prb_interpolation;
+ gNB->chest_time = get_softmodem_params()->chest_time;
+ gNB->chest_freq = get_softmodem_params()->chest_freq;
}
diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h
index 7d2184f01b..98087ea2bb 100644
--- a/executables/nr-softmodem.h
+++ b/executables/nr-softmodem.h
@@ -59,9 +59,6 @@ extern void set_function_spec_param(RU_t *ru);
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
-
-extern void init_fep_thread(PHY_VARS_gNB *);
-
void init_gNB_afterRU(void);
extern int stop_L1L2(module_id_t gnb_id);
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 6e1864f290..7b39dfdcaa 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -106,23 +106,24 @@ queue_t nr_rach_ind_queue;
static void *NRUE_phy_stub_standalone_pnf_task(void *arg);
-static int dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, int max_len)
+static size_t dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, size_t max_len)
{
- int stroff = 0;
- stroff += print_meas_log(&ue->phy_proc_tx, "L1 TX processing", NULL, NULL, output);
- stroff += print_meas_log(&ue->ulsch_encoding_stats, "ULSCH encoding", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->phy_proc_rx[0], "L1 RX processing t0", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->phy_proc_rx[1], "L1 RX processing t1", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->ue_ul_indication_stats, "UL Indication", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->rx_pdsch_stats, "PDSCH receiver", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->dlsch_decoding_stats[0], "PDSCH decoding t0", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->dlsch_decoding_stats[1], "PDSCH decoding t1", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->dlsch_deinterleaving_stats, " -> Deinterleive", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->dlsch_rate_unmatching_stats, " -> Rate Unmatch", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->dlsch_ldpc_decoding_stats, " -> LDPC Decode", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->dlsch_unscrambling_stats, "PDSCH unscrambling", NULL, NULL, output + stroff);
- stroff += print_meas_log(&ue->dlsch_rx_pdcch_stats, "PDCCH handling", NULL, NULL, output + stroff);
- return stroff;
+ const char *begin = output;
+ const char *end = output + max_len;
+ output += print_meas_log(&ue->phy_proc_tx, "L1 TX processing", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->ulsch_encoding_stats, "ULSCH encoding", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->phy_proc_rx[0], "L1 RX processing t0", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->phy_proc_rx[1], "L1 RX processing t1", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->ue_ul_indication_stats, "UL Indication", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->rx_pdsch_stats, "PDSCH receiver", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->dlsch_decoding_stats[0], "PDSCH decoding t0", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->dlsch_decoding_stats[1], "PDSCH decoding t1", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->dlsch_deinterleaving_stats, " -> Deinterleive", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->dlsch_rate_unmatching_stats, " -> Rate Unmatch", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->dlsch_ldpc_decoding_stats, " -> LDPC Decode", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->dlsch_unscrambling_stats, "PDSCH unscrambling", NULL, NULL, output, end - output);
+ output += print_meas_log(&ue->dlsch_rx_pdcch_stats, "PDCCH handling", NULL, NULL, output, end - output);
+ return output - begin;
}
static void *nrL1_UE_stats_thread(void *param)
@@ -1108,8 +1109,10 @@ void init_NR_UE_threads(int nb_inst) {
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX);
- pthread_t stat_pthread;
- threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, "L1_UE_stats", -1, OAI_PRIORITY_RT_LOW);
+ if (!IS_SOFTMODEM_NOSTATS_BIT) {
+ pthread_t stat_pthread;
+ threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, "L1_UE_stats", -1, OAI_PRIORITY_RT_LOW);
+ }
}
}
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 2347055402..de3c108841 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -259,13 +259,11 @@ void init_tpools(uint8_t nun_dlsch_threads) {
}
static void get_options(void) {
- nrUE_params.ofdm_offset_divisor = 8;
paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ;
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
+ config_get(cmdline_params,numparams,NULL);
config_process_cmdline( cmdline_params,numparams,NULL);
-
-
if (vcdflag > 0)
ouput_vcd = 1;
}
@@ -317,8 +315,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->rf_map.card = card_offset;
UE->rf_map.chain = CC_id + chain_offset;
- LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, do_prb_interpolation %d\n",
- UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->prb_interpolation);
+ LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d\n",
+ UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq);
// Set FP variables
@@ -330,6 +328,7 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ssb_start_subcarrier %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ssb_start_subcarrier);
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor;
+ UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations;
}
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 95914678e5..995d81f19c 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -7,10 +7,11 @@
-#define CONFIG_HLP_IF_FREQ "IF frequency for RF, if needed"
-#define CONFIG_HLP_IF_FREQ_OFF "UL IF frequency offset for RF, if needed"
+#define CONFIG_HLP_IF_FREQ "IF frequency for RF, if needed\n"
+#define CONFIG_HLP_IF_FREQ_OFF "UL IF frequency offset for RF, if needed\n"
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
#define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n"
+#define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
@@ -30,8 +31,9 @@
#define CMDLINE_NRUEPARAMS_DESC { \
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
- {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \
- {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:(uint32_t *)&nrUE_params.ofdm_offset_divisor, defuintval:UINT_MAX, TYPE_UINT32, 0}, \
+ {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, u8ptr:&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \
+ {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:&nrUE_params.ofdm_offset_divisor, defuintval:8, TYPE_UINT32, 0}, \
+ {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, u8ptr:&nrUE_params.max_ldpc_iterations, defuintval:5, TYPE_UINT8, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, strptr:(char **)&uecap_file, defstrval:"./uecap.xml", TYPE_STRING, 0}, \
@@ -67,7 +69,8 @@
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"if_freq" , CONFIG_HLP_IF_FREQ, 0, u64ptr:&(UE->if_freq), defuintval:0, TYPE_UINT64,0}, \
{"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, iptr:&(UE->if_freq_off), defuintval:0, TYPE_INT, 0}, \
- {"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&(UE->prb_interpolation), defintval:0, TYPE_INT, 0}, \
+ {"chest-freq", CONFIG_HLP_CHESTFREQ, 0, iptr:&(UE->chest_freq), defintval:0, TYPE_INT, 0}, \
+ {"chest-time", CONFIG_HLP_CHESTTIME, 0, iptr:&(UE->chest_time), defintval:0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \
}
@@ -76,6 +79,7 @@ typedef struct {
uint64_t optmask; //mask to store boolean config options
uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol
uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
+ uint8_t max_ldpc_iterations; // number of maximum LDPC iterations
tpool_t Tpool; // thread pool
} nrUE_params_t;
extern uint64_t get_nrUE_optmask(void);
diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c
index c78fc70243..bf30cab847 100644
--- a/executables/softmodem-common.c
+++ b/executables/softmodem-common.c
@@ -85,6 +85,7 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) {
}
void get_common_options(uint32_t execmask) {
+ int32_t stats_disabled = 0;
uint32_t online_log_messages=0;
uint32_t glog_level=0 ;
uint32_t start_telnetsrv = 0, start_telnetclt = 0;
@@ -149,6 +150,8 @@ void get_common_options(uint32_t execmask) {
if(worker_config != NULL) set_worker_conf(worker_config);
nfapi_setmode(nfapi_mode);
+ if (stats_disabled)
+ set_softmodem_optmask(SOFTMODEM_NOSTATS_BIT);
}
void softmodem_printresources(int sig, telnet_printfunc_t pf) {
struct rusage usage;
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index 72a9491f27..a2ba680234 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -72,7 +72,8 @@ extern "C"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_256QAM "Use the 256 QAM mcs table for PDSCH\n"
-#define CONFIG_HLP_PRBINTER "Do PRB based averaging of channel estimates. Frequency domain linear interpolation by default\n"
+#define CONFIG_HLP_CHESTFREQ "Set channel estimation type in frequency domain. 0-Linear interpolation (default). 1-PRB based averaging of channel estimates in frequency. \n"
+#define CONFIG_HLP_CHESTTIME "Set channel estimation type in time domain. 0-Symbols take estimates of the last preceding DMRS symbol (default). 1-Symbol based averaging of channel estimates in time. \n"
#define CONFIG_HLP_NONSTOP "Go back to frame sync mode after 100 consecutive PBCH failures\n"
//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation"
@@ -100,6 +101,7 @@ extern "C"
#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR\n"
#define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n"
#define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n"
+#define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters common to eNodeB and UE */
@@ -122,7 +124,8 @@ extern "C"
#define TUNE_OFFSET softmodem_params.tune_offset
#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync
#define USIM_TEST softmodem_params.usim_test
-#define PRB_INTERPOLATION softmodem_params.prb_interpolation
+#define CHEST_FREQ softmodem_params.chest_freq
+#define CHEST_TIME softmodem_params.chest_time
#define NFAPI softmodem_params.nfapi
#define NSA softmodem_params.nsa
#define NODE_NUMBER softmodem_params.node_number
@@ -160,14 +163,16 @@ extern int usrp_tx_thread;
{"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_INT, 0}, \
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
+ {"chest-freq", CONFIG_HLP_CHESTFREQ, 0, iptr:&CHEST_FREQ, defintval:0, TYPE_INT, 0}, \
+ {"chest-time", CONFIG_HLP_CHESTTIME, 0, iptr:&CHEST_TIME, defintval:0, TYPE_INT, 0}, \
{"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, iptr:&NSA, defintval:0, TYPE_INT, 0}, \
{"node-number", NULL, 0, u16ptr:&NODE_NUMBER, defuintval:0, TYPE_UINT16, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
- {"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
{"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, iptr:&EMULATE_L1, defintval:0, TYPE_INT, 0}, \
{"continuous-tx", CONFIG_HLP_CONTINUOUS_TX,PARAMFLAG_BOOL, iptr:&CONTINUOUS_TX, defintval:0, TYPE_INT, 0}, \
+ {"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, iptr:&stats_disabled, defintval:0, TYPE_INT, 0}, \
}
#define CONFIG_HLP_NSA "Enable NSA mode \n"
@@ -206,6 +211,7 @@ extern int usrp_tx_thread;
#define SOFTMODEM_NONBIOT_BIT (1<<2)
#define SOFTMODEM_RFSIM_BIT (1<<10)
#define SOFTMODEM_SIML1_BIT (1<<12)
+#define SOFTMODEM_DLSIM_BIT (1<<13)
#define SOFTMODEM_DOSCOPE_BIT (1<<15)
#define SOFTMODEM_RECPLAY_BIT (1<<16)
#define SOFTMODEM_TELNETCLT_BIT (1<<17)
@@ -213,6 +219,7 @@ extern int usrp_tx_thread;
#define SOFTMODEM_GNB_BIT (1<<21)
#define SOFTMODEM_4GUE_BIT (1<<22)
#define SOFTMODEM_5GUE_BIT (1<<23)
+#define SOFTMODEM_NOSTATS_BIT (1<<24)
#define SOFTMODEM_FUNC_BITS (SOFTMODEM_ENB_BIT | SOFTMODEM_GNB_BIT | SOFTMODEM_5GUE_BIT | SOFTMODEM_4GUE_BIT)
#define MAPPING_SOFTMODEM_FUNCTIONS {{"enb",SOFTMODEM_ENB_BIT},{"gnb",SOFTMODEM_GNB_BIT},{"4Gue",SOFTMODEM_4GUE_BIT},{"5Gue",SOFTMODEM_5GUE_BIT}}
@@ -222,6 +229,7 @@ extern int usrp_tx_thread;
#define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT)
#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT)
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)
+#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT)
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
@@ -229,6 +237,7 @@ extern int usrp_tx_thread;
#define IS_SOFTMODEM_GNB_BIT ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT)
#define IS_SOFTMODEM_4GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_4GUE_BIT)
#define IS_SOFTMODEM_5GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_5GUE_BIT)
+#define IS_SOFTMODEM_NOSTATS_BIT ( get_softmodem_optmask() & SOFTMODEM_NOSTATS_BIT)
typedef struct {
uint64_t optmask;
@@ -251,7 +260,9 @@ typedef struct {
double tune_offset;
int hw_timing_advance;
uint32_t send_dmrs_sync;
- int prb_interpolation;
+ int use_256qam_table;
+ int chest_time;
+ int chest_freq;
uint8_t nfapi;
int nsa;
uint16_t node_number;
diff --git a/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt b/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt
new file mode 100644
index 0000000000..2983268dac
--- /dev/null
+++ b/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt
@@ -0,0 +1,64 @@
+SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX
+-2.000000 1.000000 0.346185 0.258473 44.551218 31.688925 357.883903 217.655668 12.810778 326.852166 5.000000 0.000000 5
+-1.900000 1.000000 0.345395 0.256275 40.787109 4.190954 65.926488 215.687102 4.300128 230.585721 5.000000 0.000000 5
+-1.800000 1.000000 0.343100 0.253634 40.748628 3.912915 56.669470 215.314020 4.139156 227.806468 5.000000 0.000000 5
+-1.700000 1.000000 0.341806 0.250634 40.550845 3.347808 56.032851 216.839001 5.959734 244.483352 5.000000 0.000000 5
+-1.600000 1.000000 0.339245 0.248129 40.457158 3.735092 56.853508 215.747244 4.995522 242.867659 5.000000 0.000000 5
+-1.500000 1.000000 0.337230 0.245763 41.178595 4.297429 56.265874 215.785600 4.151781 227.795995 5.000000 0.000000 5
+-1.400000 1.000000 0.335131 0.243311 39.915221 2.739586 55.454917 216.866764 6.547848 251.528327 5.000000 0.000000 5
+-1.300000 1.000000 0.333085 0.240664 40.119215 3.044973 55.978253 216.208443 4.459816 228.810686 5.000000 0.000000 5
+-1.200000 1.000000 0.330664 0.238769 40.507713 2.998241 55.701876 215.868796 3.778455 226.049304 5.000000 0.000000 5
+-1.100000 1.000000 0.329130 0.235812 41.038895 4.522472 56.760814 215.654663 4.746822 236.021980 5.000000 0.000000 5
+-1.000000 1.000000 0.325980 0.233534 41.067622 4.626711 57.444142 215.260535 3.481966 225.512853 5.000000 0.000000 5
+-0.900000 1.000000 0.323823 0.230863 40.683316 3.689159 56.208182 215.560917 5.180017 243.603452 5.000000 0.000000 5
+-0.800000 1.000000 0.321004 0.228222 41.643513 4.717568 58.502452 215.630891 4.283475 238.574145 5.000000 0.000000 5
+-0.700000 1.000000 0.317983 0.225520 41.214547 3.941824 56.054211 215.910346 4.375081 227.444626 5.000000 0.000000 5
+-0.600000 1.000000 0.316243 0.222903 40.834442 4.370416 56.765508 215.153296 3.617927 226.280086 5.000000 0.000000 5
+-0.500000 1.000000 0.312886 0.220473 40.178174 4.185502 64.657291 219.647151 4.454154 236.473446 5.000000 0.000000 5
+-0.400000 1.000000 0.309757 0.217536 40.240385 3.172484 55.751563 217.761119 3.900779 228.757195 5.000000 0.000000 5
+-0.300000 1.000000 0.305464 0.215229 40.852271 3.761739 56.158869 217.830497 4.087453 230.237764 5.000000 0.000000 5
+-0.200000 1.000000 0.302919 0.212364 40.531166 3.688281 56.426841 217.657657 5.498697 253.516146 5.000000 0.000000 5
+-0.100000 1.000000 0.298246 0.209310 41.058364 4.140510 59.959571 217.519279 4.087389 228.768313 5.000000 0.000000 5
+0.000000 1.000000 0.294110 0.207107 40.436486 3.604369 55.788895 217.853044 4.012624 236.118036 5.000000 0.000000 5
+0.100000 1.000000 0.288139 0.204033 40.603738 4.045866 57.560760 217.046816 4.583841 244.429411 5.000000 0.000000 5
+0.200000 1.000000 0.285604 0.201954 40.494607 3.886199 59.431970 217.322824 4.080988 233.317513 5.000000 0.000000 5
+0.300000 1.000000 0.278478 0.198929 40.311327 3.452837 56.124657 217.319394 4.434358 232.534720 5.000000 0.000000 5
+0.400000 1.000000 0.270992 0.196299 40.649243 3.415612 56.204178 218.079445 4.990947 245.055337 5.000000 0.000000 5
+0.500000 1.000000 0.263944 0.193661 40.464299 3.622703 56.602842 218.555364 3.936432 229.481159 5.000000 0.000000 5
+0.600000 1.000000 0.256340 0.191194 40.200314 2.474984 53.432412 216.547260 3.695211 227.198078 5.000000 0.000000 5
+0.700000 1.000000 0.251578 0.188606 40.111945 3.029821 54.900896 216.581752 4.247622 237.358365 5.000000 0.000000 5
+0.800000 1.000000 0.234558 0.184742 39.533282 1.182169 42.753097 215.462335 2.960246 226.716604 5.000000 0.000000 5
+0.900000 1.000000 0.225915 0.182691 39.851294 1.108193 42.180342 216.404194 4.450720 228.482353 5.000000 0.000000 5
+1.000000 1.000000 0.216180 0.179994 40.721936 3.302539 56.032206 217.082196 4.599188 227.979232 5.000000 0.000000 5
+1.100000 1.000000 0.203481 0.177332 41.006217 3.798207 56.014901 216.204345 4.292145 227.297386 5.000000 0.000000 5
+1.200000 1.000000 0.188297 0.174121 40.739289 3.269948 56.653507 216.585873 6.250858 251.207034 5.000000 0.000000 5
+1.300000 1.000000 0.172624 0.171622 41.215540 4.783342 55.692883 215.885639 3.629370 226.473280 5.000000 0.000000 5
+1.400000 1.000000 0.156483 0.169110 40.289903 3.749338 56.290861 215.663761 4.176366 225.824735 5.000000 0.000000 5
+1.500000 1.000000 0.136293 0.165692 42.208932 6.070189 69.182665 216.390504 4.816283 235.417446 5.000000 0.000000 5
+1.600000 1.000000 0.125127 0.163325 40.890581 3.941185 56.491504 215.752348 4.426511 226.425984 5.000000 0.000000 5
+1.700000 1.000000 0.104593 0.159971 41.263557 4.128935 57.062514 217.284932 5.311288 249.647163 5.000000 0.000000 5
+1.800000 1.000000 0.091397 0.157460 40.273078 3.062810 55.546913 217.252505 6.331426 251.175692 5.000000 0.000000 5
+1.900000 1.000000 0.078256 0.154628 40.407489 3.419342 56.316166 216.967648 4.712664 245.093313 5.000000 0.000000 5
+2.000000 1.000000 0.065221 0.152571 40.660365 4.317854 57.537407 216.198346 4.991856 245.173269 5.000000 0.000000 5
+2.100000 1.000000 0.053694 0.148885 40.355654 4.062614 60.051963 215.797667 4.447252 236.221454 5.000000 0.000000 5
+2.200000 1.000000 0.042182 0.146229 40.613562 4.124655 56.201536 216.117304 4.060825 227.115987 5.000000 0.000000 5
+2.300000 1.000000 0.034334 0.143612 40.465884 3.541452 55.067611 215.575953 4.891719 244.546802 5.000000 0.000000 5
+2.400000 1.000000 0.026641 0.140869 41.074690 4.697458 61.619188 216.069185 4.700827 233.830937 5.000000 0.000000 5
+2.500000 1.000000 0.019976 0.138112 40.766971 4.274128 58.871741 215.761570 5.633731 249.753931 5.000000 0.000000 5
+2.600000 1.000000 0.012826 0.135122 40.559343 2.952804 54.017706 215.835161 4.039993 226.822103 5.000000 0.000000 5
+2.700000 1.000000 0.010550 0.132915 40.985193 3.330639 55.013950 215.975836 4.240744 227.040703 5.000000 0.000000 5
+2.800000 1.000000 0.007327 0.130133 39.778804 3.002485 56.610555 216.462786 7.082268 265.051418 5.000000 0.000000 5
+2.900000 1.000000 0.004038 0.126763 40.327795 3.934211 55.515352 215.982666 4.626198 230.696124 5.000000 0.000000 5
+3.000000 1.000000 0.003087 0.124336 40.337807 3.537021 55.101627 215.468662 4.177203 230.789145 5.000000 0.000000 5
+3.100000 1.000000 0.001576 0.121689 39.812195 3.116738 55.422687 215.797778 4.091192 225.897780 5.000000 0.000000 5
+3.200000 0.980000 0.001000 0.118928 39.853764 2.871322 56.405555 215.562722 4.187466 232.598421 5.000000 0.000000 5
+3.300000 0.960000 0.000623 0.116065 40.440328 3.580650 56.738889 216.165848 4.735158 240.329999 5.000000 0.000000 5
+3.400000 0.850000 0.000303 0.113505 40.974107 4.291544 56.280236 215.889562 4.448049 237.556780 5.000000 0.000000 5
+3.500000 0.690000 0.000152 0.111010 41.508631 4.251791 56.198873 216.740295 4.889693 242.922934 5.000000 0.000000 5
+3.600000 0.530000 0.000102 0.108493 40.065231 3.643794 57.120823 216.887338 5.242621 250.003843 5.000000 0.000000 5
+3.700000 0.320000 0.000043 0.105612 40.462159 4.162383 56.782173 216.465615 3.846314 227.022697 5.000000 0.000000 5
+3.800000 0.210000 0.000032 0.103084 42.192455 6.207380 64.648964 217.030913 4.482820 228.095918 5.000000 0.000000 5
+3.900000 0.110000 0.000013 0.100391 40.640286 3.715782 55.922914 217.726055 4.553212 236.362804 5.000000 0.000000 5
+4.000000 0.050000 0.000006 0.097518 40.437760 2.838308 54.764308 218.230040 4.309275 237.932625 5.000000 0.000000 5
+4.100000 0.020000 0.000002 0.095436 41.347934 4.608500 64.182062 217.408836 4.385757 228.219627 5.000000 0.000000 5
+4.200000 0.000000 0.000000 0.092396 40.782371 3.621708 55.984245 217.579878 4.102149 228.145363 5.000000 0.000000 5
diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index d13dc5d1c5..8cc1bda782 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -217,7 +217,7 @@ void oai_create_enb(void) {
}
// This will cause phy_config_request to be installed. That will result in RRC configuring the PHY
- // that will result in eNB->configured being set to TRUE.
+ // that will result in eNB->configured being set to true.
// See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values
if (RC.eNB[0][0]->if_inst==0 || RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it\n");
@@ -267,7 +267,7 @@ void oai_create_gnb(void) {
// This will cause phy_config_request to be installed. That will result in RRC configuring the PHY
- // that will result in gNB->configured being set to TRUE.
+ // that will result in gNB->configured being set to true.
// See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values
if (RC.gNB[0]->if_inst==0 || RC.gNB[0]->if_inst->NR_PHY_config_req==0 || RC.gNB[0]->if_inst->NR_Schedule_response==0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0][0]->if_inst->NR_PHY_config_req is not installed - install it\n");
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index fd9af01720..10f881bae6 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -87,7 +87,7 @@ typedef struct {
// N_CCE is L, or number of CCEs for DCI
int N_CCE;
uint8_t payloadSize;
- uint8_t payloadBits[16];
+ uint8_t payloadBits[16] __attribute__((aligned(16))); // will be cast as uint64
//fapi_nr_dci_pdu_rel15_t dci;
} fapi_nr_dci_indication_pdu_t;
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index 8b564a5e37..3a7dd8d523 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -738,7 +738,7 @@ typedef struct {
// The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8
uint16_t PayloadSizeBits;
// DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
- uint8_t Payload[DCI_PAYLOAD_BYTE_LEN];
+ uint8_t Payload[DCI_PAYLOAD_BYTE_LEN] __attribute__((aligned(32)));
} nfapi_nr_dl_dci_pdu_t;
@@ -1666,41 +1666,34 @@ typedef struct
} nfapi_nr_uci_indication_t;
-//3.4.10 srs_indication
-//table 3-73
-typedef struct
-{
- uint8_t rb_snr;
-}nfapi_nr_srs_indication_reported_symbol_resource_block_t;
+/// 5G PHY FAPI Specification: SRS indication - Section 3.4.10, Table 3-73
-typedef struct
-{
- uint16_t num_rbs;
+typedef struct {
+ uint8_t rb_snr; // SNR value in dB. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB, 0xff will be set if this field is invalid.
+} nfapi_nr_srs_indication_reported_symbol_resource_block_t;
+
+typedef struct {
+ uint16_t num_rbs; // Number of PRBs to be reported for this SRS PDU. Value: 0 -> 272.
nfapi_nr_srs_indication_reported_symbol_resource_block_t* rb_list;
-}nfapi_nr_srs_indication_reported_symbol_t;
+} nfapi_nr_srs_indication_reported_symbol_t;
-#define NFAPI_NR_SRS_IND_MAX_PDU 100
-typedef struct
-{
- uint32_t handle;
- uint16_t rnti;
- uint16_t timing_advance;
- uint8_t num_symbols;
- uint8_t wide_band_snr;
- uint8_t num_reported_symbols;
+typedef struct {
+ uint32_t handle; // The handle passed to the PHY in the the UL_TTI.request SRS PDU.
+ uint16_t rnti; // The RNTI passed to the PHY in the UL_TTI.request SRS PDU. Value: 1 -> 65535.
+ uint16_t timing_advance; // Timing advance TA measured for the UE [TS 38.213, Section 4.2]. NTA_new = NTA_old + (TA − 31) * 16 * 64 / (2^u). Value: 0 -> 63. 0xffff should be set if this field is invalid.
+ uint8_t num_symbols; // Number of symbols for SRS. Value: 1 -> 4. If a PHY does not report for individual symbols then this parameter should be set to 1.
+ uint8_t wide_band_snr; // SNR value in dB measured within configured SRS bandwidth on each symbol. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB. 0xff will be set if this field is invalid.
+ uint8_t num_reported_symbols; // Number of symbols reported in this message. This allows PHY to report individual symbols or aggregated symbols where this field will be set to 1. Value: 1 -> 4.
nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list;
+} nfapi_nr_srs_indication_pdu_t;
-}nfapi_nr_srs_indication_pdu_t;
-
-typedef struct
-{
+typedef struct {
nfapi_p7_message_header_t header;
- uint16_t sfn;
- uint16_t slot;
- uint8_t number_of_pdus;
+ uint16_t sfn; // SFN. Value: 0 -> 1023
+ uint16_t slot; // Slot. Value: 0 -> 159
+ uint8_t number_of_pdus; // Number of PDUs included in this message. Value: 0 -> 255
nfapi_nr_srs_indication_pdu_t* pdu_list;
-
} nfapi_nr_srs_indication_t;
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
index 264b25deca..af02a16054 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
@@ -814,7 +814,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
llr_t *s1,*s2,*yp1,*yp2,*yp;
unsigned int i,j,iind;//,pi;
unsigned char iteration_cnt=0;
- unsigned int crc,oldcrc,crc_len;
+ unsigned int crc, crc_len;
uint8_t temp;
#if defined(__x86_64__) || defined(__i386__)
__m128i *yp128;
@@ -1233,8 +1233,8 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
}
// check the CRC
- oldcrc= *((unsigned int *)(&decoded_bytes[(n>>3)-crc_len]));
-
+ uint32_t oldcrc;
+ memcpy(&oldcrc, &decoded_bytes[(n >> 3) - crc_len], crc_len);
switch (crc_type) {
case CRC24_A:
oldcrc&=0x00ffffff;
diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h
index 9972a47ee7..1854f28fa7 100644
--- a/openair1/PHY/CODING/coding_defs.h
+++ b/openair1/PHY/CODING/coding_defs.h
@@ -38,7 +38,6 @@
#define MAX_TURBO_ITERATIONS_MBSFN 8
#define MAX_TURBO_ITERATIONS max_turbo_iterations
-#define MAX_LDPC_ITERATIONS 5
#define MAX_LDPC_ITERATIONS_MBSFN 4
#define LTE_NULL 2
diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c
index 9ad18cc1a6..471b26fe24 100644
--- a/openair1/PHY/CODING/crc_byte.c
+++ b/openair1/PHY/CODING/crc_byte.c
@@ -244,11 +244,11 @@ crc16 (unsigned char * inptr, int bitlen)
while (octetlen-- > 0) {
- crc = (crc << 8) ^ (crc16Table[(*inptr++) ^ (crc >> 24)] << 16);
+ crc = (crc << 8) ^ (((uint32_t)crc16Table[(*inptr++) ^ (crc >> 24)]) << 16);
}
if (resbit > 0)
- crc = (crc << resbit) ^ (crc16Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16);
+ crc = (crc << resbit) ^ (((uint32_t)crc16Table[(*inptr) >> (8 - resbit) ^ (crc >> (32 - resbit))]) << 16);
return crc;
}
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/logo.png b/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/logo.png
deleted file mode 100644
index 7b785ca051..0000000000
Binary files a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/logo.png and /dev/null differ
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.pdf b/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.pdf
deleted file mode 100644
index 590dab5ce2..0000000000
Binary files a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.pdf and /dev/null differ
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.tex b/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.tex
deleted file mode 100644
index 019b51aa96..0000000000
--- a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.tex
+++ /dev/null
@@ -1,960 +0,0 @@
-%
-% Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
-% contributor license agreements. See the NOTICE file distributed with
-% this work for additional information regarding copyright ownership.
-% The OpenAirInterface Software Alliance licenses this file to You under
-% the OAI Public License, Version 1.1 (the "License"); you may not use this file
-% except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.openairinterface.org/?page_id=698
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%-------------------------------------------------------------------------------
-% For more information about the OpenAirInterface (OAI) Software Alliance:
-% contact@openairinterface.org
-%
-
-\documentclass{article}
-
-\usepackage[a4paper, total={6in, 8in}]{geometry}
-
-\usepackage{amsmath}
-\usepackage{amsfonts}
-\usepackage{amssymb}
-\usepackage{booktabs}
-\usepackage{url}
-\usepackage{tcolorbox}
-
-\usepackage{tikz}
-\usetikzlibrary{arrows,decorations,shapes,backgrounds,patterns}
-\usepackage{pgfplots}
-\pgfplotsset{compat=newest}
-\definecolor{green}{RGB}{32,127,43}
-\usetikzlibrary{calc}
-
-\usepackage{listings}
-\lstdefinestyle{customc}{
- belowcaptionskip=1\baselineskip,
- breaklines=true,
- frame=L,
- xleftmargin=\parindent,
- language=C,
- showstringspaces=false,
- basicstyle=\footnotesize\ttfamily,
- keywordstyle=\bfseries\color{green!40!black},
- commentstyle=\itshape\color{purple!40!black},
- identifierstyle=\color{blue},
- stringstyle=\color{orange},
-}
-\lstset{escapechar=@,style=customc}
-
-\title{NR LDPC Decoder}
-\author{Sebastian Wagner (TCL)}
-\date{\today}
-
-\def\0{\mathbf{0}}
-\def\b{\mathbf{b}}
-\def\Bbb{\mathbb{B}}
-\def\Bcal{\mathcal{B}}
-\def\c{\mathbf{c}}
-\def\C{\mathbf{C}}
-\def\Cbb{\mathbb{C}}
-\def\Ccal{\mathcal{C}}
-\def\eqdef{\triangleq}
-\def\g{\mathbf{g}}
-\def\G{\mathbf{G}}
-\def\Gcal{\mathcal{G}}
-\def\h{\mathbf{h}}
-\def\H{\mathbf{H}}
-\def\Hbg{\mathbf{H}_\mathrm{BG}}
-\def\Hbgo{\mathbf{H}_\mathrm{BG1}}
-\def\Hbgt{\mathbf{H}_\mathrm{BG2}}
-\def\I{\mathbf{I}}
-\def\Kb{{K_b}}
-\def\m{\mathbf{m}}
-\def\Mb{{M_b}}
-\def\Nb{{N_b}}
-\def\Nbb{\mathbb{N}}
-\def\n{\mathbf{n}}
-\def\nr{{n_{\rm r}}}
-\def\nt{{n_{\rm t}}}
-\def\s{\mathbf{s}}
-\def\SNR{\mathsf{SNR}}
-\def\y{\mathbf{y}}
-\def\z{\mathbf{z}}
-\def\Z{\mathbf{Z}}
-\def\Zc{{Z_c}}
-
-
-\def\herm{\mathsf{H}}
-\def\trans{\mathsf{T}}
-\def\EE{\mathsf{E}}
-\newcommand{\sgn}{\operatorname{sgn}}
-
-\begin{document}
-
-\maketitle
-
-\begin{tikzpicture}[remember picture,overlay]
- \node[anchor=north west,inner sep=0pt] at (current page.north west)
- {\includegraphics[scale=0.5]{logo.png}};
-\end{tikzpicture}
-
-
-\begin{center}Currently Supported:\end{center}
-\tcbox[center]{
- \begin{tabular}{lll}
- \toprule
- \textbf{BG} & \textbf{Lifting Size Z} & \textbf{Code Rate R} \\
- \midrule
- 1 & all & 1/3, 2/3, 8/9 \\
- 2 & all & 1/5, 1/3, 2/3 \\
- \bottomrule
- \end{tabular}
-}
-
-\paragraph{Version 1.0:}
-\begin{itemize}
-\item Initial version
-\end{itemize}
-
-\paragraph{Version 2.0:}
-\begin{itemize}
-\item Enhancements in message passing:
- \begin{itemize}
- \item LUTs replaced by smaller BG-specific parameters
- \item Inefficient load/store replaced by circular memcpy
- \end{itemize}
-\item Bug fixes:
- \begin{itemize}
- \item Fixed bug in function \texttt{llr2CnProcBuf}
- \item Corrected input LLR dynamic range in BLER simulations
- \end{itemize}
-\item Results:
- \begin{itemize}
- \item Size of LUTs reduced significantly (60MB to 200KB)
- \item Siginifcantly enhances execution time (factor 3.5)
- \item Improved BLER performance (all simulation results have been updated)
- \end{itemize}
-\end{itemize}
-
-
-\newpage
-\tableofcontents
-
-\newpage
-\section{Introduction}
-\label{sec:introduction}
-
-Low Density Parity Check (LDPC) codes have been developed by Gallager in 1963 \cite{gallager1962low}. They are linear error correcting codes that are capacity-achieving for large block length and are completely described by their Parity Check Matrix (PCM) $\H^{M\times N}$. The PCM $\H$ defines $M$ constraints on the codeword $\c$ of length $N$ such that
-\begin{equation}
- \label{eq:29}
- \H\c = \0.
-\end{equation}
-The number of information bits $B$ that can be encoded with $\H$ is given by $B=N-M$. Hence the code rate $R$ of $\H$ reads
-\begin{equation}
- \label{eq:37}
- R = \frac{B}{N} = 1-\frac{M}{N}.
-\end{equation}
-
-
-\subsection{LDPC in NR}
-\label{sec:ldpc-nr}
-
-NR uses quasi-cyclic (QC) Protograph LDPC codes, i.e. a smaller graph, called Base Graph (BG), is defined and utilized to construct the larger PCM. This has the advantage that the large PCM does not have to be stored in memory and allows for a more efficient implementation while maintaining good decoding properties.
-Two BGs $\Hbg\in\Nbb^{\Mb\times \Nb}$ are defined in NR:
-\begin{enumerate}
-\item $\Hbgo\in\Nbb^{46\times 68}$
-\item $\Hbgt\in\Nbb^{42\times 52}$
-\end{enumerate}
-where $\Nbb$ is the set of integers. For instance the first 3 rows and 13 columns of BG2 are given by
-
-\setcounter{MaxMatrixCols}{30}
-\begin{equation*}
- \label{eq:33}
- \Hbgt =
- \begin{bmatrix}
- 9 & 117 & 204 & 26 & \emptyset & \emptyset & 189 & \emptyset & \emptyset & 205 & 0 & 0 & \emptyset & \emptyset \\
- 127 & \emptyset & \emptyset & 166 & 253 & 125 & 226 & 156 & 224 & 252 & \emptyset & 0 & 0 & \emptyset \\
- 81 & 114 & \emptyset & 44 & 52 & \emptyset & \emptyset & \emptyset & 240 & \emptyset & 1 & \emptyset & 0 & 0
- \end{bmatrix}.
-\end{equation*}
-
-To obtain the PCM $\H$ from the BG $\Hbg$, each element $\Hbg(i,j)$ in the BG is replaced by a lifting matrix of size $\Zc\times \Zc$ according to
-\begin{equation}
- \label{eq:35}
- \Hbg(i,j) =
- \begin{cases}
- \0 & \textrm{if}~ \Hbg(i,j)=\emptyset \\
- \I_{P_{ij}} & \textrm{otherwise}
- \end{cases}
-\end{equation}
-where $\I_{P_{ij}}$ is the identity matrix circularly shifted to the right by $P_{ij} = \Hbg(i,j)\mod \Zc$. Hence, the resulting PCM $\H$ will be of size $\Mb\Zc\times\Nb\Zc$.
-
-The lifting size $\Zc$ depends on the number of bits to encode. To limit the complexity, a discrete set $\mathcal{Z}$ of possible values of $\Zc$ has been defined in \cite{3gpp2017_38212} and the optimal value $\Zc$ is calculated according to
-\begin{equation}
- \label{eq:36}
- \Zc = \min_{\Z\in\mathcal{Z}}\left[Z\geq\frac{B}{\Nb}\right].
-\end{equation}
-
-The base rate of the two BGs is $1/3$ and $1/5$ for BG1 and BG2, respectively. That is, BG1 encodes $K=22\Zc$ bits and BG2 encodes $K=10\Zc$ bits. Note that the first 2 columns of BG 1 and 2 are always punctured, that is after encoding, the first $2\Zc$ bits are discarded and not transmitted.
-For instance, consider $B=500$ information bits to encode using BG2, \eqref{eq:36} yields $\Zc=64$ hence $K=640$. Since $K>B$, $K-B=140$ filler bits are appended to the information bits. The PCM $\Hbgt$ is of size $2688\times 3328$ and the $640$ bits $\b$ are encoded according to \eqref{eq:29} at a rate $R \approx 0.192$. To achieve the higher base rate of $0.2$, the first $128$ are punctured, i.e. instead of transmitting all $3328$ bits, only $3200$ are transmitted resulting in the desired rate $R=640/3200=0.2$.
-
-\subsection{LDPC Decoding}
-\label{sec:ldpc-decoding}
-
-The decoding of codeword $\c$ can be achieved via the classical message passing algorithm. This algorithm can be illustrated best using the Tanner graph of the PCM. The rows of the PCM are called check nodes (CN) since they represent the parity check equations. The parity check equation of each of these check nodes involves various bits in the codeword. Similarly, every column of the PCM corresponds to a bit and each bit is involved in several parity check equations. In the Tanner graph representation, the bits are called bit nodes (BN). Let's go back to the previous example of BG2 and assume $\Zc=2$, hence the first 3 rows and 13 columns of BG2 $\Hbgt$ read
-\begin{equation*}
- \label{eq:36}
- \Hbgt =
- \begin{bmatrix}
- 1 & 1 & 0 & 0 & \emptyset & \emptyset & 1 & \emptyset & \emptyset & 1 & 0 & 0 & \emptyset & \emptyset \\
- 1 & \emptyset & \emptyset & 0 & 1 & 1 & 0 & 0 & 0 & 0 & \emptyset & 0 & 0 & \emptyset \\
- 1 & 0 & \emptyset & 0 & 0 & \emptyset & \emptyset & \emptyset & 0 & \emptyset & 1 & \emptyset & 0 & 0
- \end{bmatrix}.
-\end{equation*}
-Replacing the elements according to \eqref{eq:35}, we obtain the first 6 rows and 26 columns of the PCM as
-\begin{equation*}
- \label{eq:39}
- \H =
- \begin{bmatrix}
- 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\
- 1 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0\\
- 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0\\
- 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0\\
- 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0\\
- 1 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1
- \end{bmatrix}.
-\end{equation*}
-
-The Tanner graph of the first 8 BNs is shown in Figure \ref{fig:tannergraph}.
-
-\begin{figure}[ht]
- \label{fig:tannergraph}
- \centering
- \def\ww{0.3cm}
- \def\hh{0.3cm}
- \tikzstyle{cnode}=[fill=white,rectangle,draw=black,thick,inner sep=2pt, minimum height=\hh,minimum width=\ww, rounded corners=1pt,text width=\ww]
- \tikzstyle{vnode}=[fill=white,circle,draw=black,thick,inner sep=2pt, minimum height=\hh,minimum width=\ww, rounded corners=1pt,text width=\ww]
- \tikzstyle{connector}=[<->,>=latex',semithick]
-
- \begin{tikzpicture}
- \tikzstyle{every node}=[node distance=1.5cm,text centered]
- % Check nodes
- \node[cnode, label=above:$v_0$] (v0) {};
- \node[cnode, label=above:$v_1$, right of=v0] (v1) {};
- \node[cnode, label=above:$v_2$, right of=v1] (v2) {};
- % Variable nodes
- \node[vnode, label=below:$c_3$, below of=v1, node distance=1.5cm] (c3) {};
- \node[vnode, label=below:$c_2$, left of=c3, node distance=1.5cm] (c2) {};
- \node[vnode, label=below:$c_1$, left of=c2, node distance=1.5cm] (c1) {};
- \node[vnode, label=below:$c_0$, left of=c1, node distance=1.5cm] (c0) {};
- \node[vnode, label=below:$c_4$, right of=c3, node distance=1.5cm] (c4) {};
- \node[vnode, label=below:$c_5$, right of=c4, node distance=1.5cm] (c5) {};
- \node[vnode, label=below:$c_6$, right of=c5, node distance=1.5cm] (c6) {};
-
- % Draw edges
- \draw (c0) edge[connector] (v1);
- \draw (c1) edge[connector] (v0);
- \draw (c1) edge[connector] (v2);
- \draw (c2) edge[connector] (v1);
- \draw (c3) edge[connector] (v0);
- \draw (c4) edge[connector] (v0);
- \draw (c4) edge[connector] (v2);
- \draw (c5) edge[connector] (v1);
- \draw (c6) edge[connector] (v0);
- \draw (c6) edge[connector] (v2);
-
- \end{tikzpicture}
-
- \caption{Tanner graph for first 7 bits nodes and 3 check nodes from \eqref{eq:39}.}
-\end{figure}
-
-The message passing algorithm is an iterative algorithm where probabilities of the bits (being either 0 or 1) are exchanged between the BNs and CNs. After sufficient iterations, the probabilities will have either converged to either 0 or 1 and the parity check equations will be satisfied, at this point, the codeword has been decoded correctly.
-
-\newpage
-\section{LDPC Decoder Implementation}
-\label{sec:ldpc-implementation}
-
-The implementation on a general purpose processor (GPP) has to take advantage of potential instruction extension of the processor architecture. We focus on the Intel x86 instruction set architecture (ISA) and its advanced vector extension (AVX). In particular, we utilize AVX2 with its 256-bit single instruction multiple data (SIMD) format. In order to utilize AVX2 to speed up the processing at the CNs and BNs, the corresponding data has to be ordered/aligned in a specific way. The processing flow of the LDPC decoder is depicted in \ref{fig:ldpc_decoder_flow}.
-
-\begin{figure}[ht]
- \label{fig:ldpc_decoder_flow}
- \centering
- \def\ww{0.3cm}
- \def\hh{0.3cm}
- \tikzstyle{func}=[,draw=none]
- \tikzstyle{connector}=[->,>=latex',semithick]
-
- \begin{tikzpicture}
- \tikzstyle{every node}=[node distance=2.5cm,text centered]
- % Check nodes
- % First iteration
- \node[func] (llr2llrProcBuf) {\texttt{llr2llrProcBuf}};
- \node[func, above of=llr2llrProcBuf] (llr2CnProcBuf) {\texttt{llr2CnProcBuf}};
- \node[func, above right of=llr2CnProcBuf] (cnProc1) {\texttt{cnProc}};
- \node[func, below right of=cnProc1] (cn2bnProcBuf1) {\texttt{cn2bnProcBuf}};
- \node[func, below of=cn2bnProcBuf1] (bnProcPc1) {\texttt{bnProcPc}};
-
- % Iterations
- \node[func, right of=cnProc1, node distance=7cm] (cnProc) {\texttt{cnProc}};
- \node[func, below right of=cnProc] (cn2bnProcBuf) {\texttt{cn2bnProcBuf}};
- \node[func, below of=cn2bnProcBuf] (bnProcPc) {\texttt{bnProcPc}};
- \node[func, below left of=cnProc] (bn2cnProcBuf) {\texttt{bn2cnProcBuf}};
- \node[func, below of=bn2cnProcBuf] (bnProc) {\texttt{bnProc}};
-
- % Post processing
- \node[func, below of=bnProcPc] (llrRes2llrOut) {\texttt{llrRes2llrOut}};
- \node[func, below of=llrRes2llrOut, node distance=1cm] (llr2bit) {\texttt{llr2bit}};
-
- % Draw edges
- \draw (llr2llrProcBuf) edge[connector] (llr2CnProcBuf);
- \draw (llr2CnProcBuf) edge[connector] (cnProc1);
- \draw (cnProc1) edge[connector] (cn2bnProcBuf1);
- \draw (cn2bnProcBuf1) edge[connector] (bnProcPc1);
-
- \draw (bnProcPc) edge[connector] (bnProc);
- \draw (bnProc) edge[connector] (bn2cnProcBuf);
- \draw (bn2cnProcBuf) edge[connector] node[above left] {\texttt{cnProcPc}} (cnProc);
- \draw (cnProc) edge[connector] (cn2bnProcBuf);
- \draw (cn2bnProcBuf) edge[connector] (bnProcPc);
-
- \draw (bnProcPc1) edge[connector] (bnProc);
-
- \draw (bnProcPc) edge[connector] node[left] {iterations done} (llrRes2llrOut);
- \draw (llrRes2llrOut) edge[connector] (llr2bit);
-
- % Boxes
- \node[inner sep=0pt,above right of=cn2bnProcBuf1, node distance = 2.5cm] (ref) {};
-
- \draw[fill=black,opacity=.2, rounded corners] (llr2llrProcBuf.south west) rectangle ($(ref) + (-.5cm,.5cm)$);
- \draw[fill=black,opacity=.2, rounded corners] ($(ref) + (.5cm,.5cm)$) rectangle ($(bnProcPc.south east) + (.4cm,0)$);
-
- \node[func, above of=cnProc1, node distance=.8cm] (iter1) {\textbf{First Iteration}};
- \node[func, above of=cnProc , node distance=.8cm] (iterX) {\textbf{Subsequent Iterations}};
-
- \end{tikzpicture}
-
- \caption{LDPC Decoder processing flow.}
-\end{figure}
-
-The functions involved are described in more detail in Table \ref{tab:sum_func}.
-
-\begin{table}[ht]
- \centering
- \begin{tabular}{ll}
- \toprule
- \textbf{Function} & \textbf{Description} \\
- \midrule
- \texttt{llr2llrProcBuf} & Copies input LLRs to LLR processing buffer \\
- \texttt{llr2CnProcBuf} & Copies input LLRs to CN processing buffer \\
- \texttt{cnProc} & Performs CN signal processing \\
- \texttt{cnProcPc} & Performs parity check \\
- \texttt{cn2bnProcBuf} & Copies the CN results to the BN processing buffer \\
- \texttt{bnProcPc} & Performs BN processing for parity check and/or hard-decision \\
- \texttt{bnProc} & Utilizes the results of \texttt{bnProcPc} to compute LLRs for CN processing \\
- \texttt{bn2cnProcBuf} & Copies the BN results to the CN processing buffer \\
- \texttt{llrRes2llrOut} & Copies the results of \texttt{bnProcPc} to output LLRs \\
- \texttt{llr2bit} & Performs hard-decision on the output LLRs \\
- \bottomrule
- \end{tabular}
- \caption{Summary of the LDPC decoder functions.}
- \label{tab:sum_func}
-\end{table}
-
-The input LLRs are assumed to be 8-bit and aligned on 32 bytes. CN processing is carried out in 8-bit whereas BN processing is done in 16 bit. Subsequently, the processing tasks at the CNs and BNs are explained in more detail.
-
-\newpage
-\subsection{Check Node Processing}
-\label{sec:check-node-proc}
-
-Denote $q_{ij}$ the value from BN $j$ to CN $i$ and let $\Bcal_i$ be the set of connected BNs to the $i$th CN. Then, using the min-sum approximation, CN $i$ has to carry out the following operation for each connected BN.
-\begin{equation}
- \label{eq:40}
- r_{ji} = \prod_{j'\in\Bcal_i\setminus j}\sgn q_{ij'}\min_{j'\in\Bcal_i\setminus j} |q_{ij'}|
-\end{equation}
-where $r_{ji}$ is the value returned to BN $j$ from CN $i$. There are $\Mb = \{46,42\}$ CNs in BG 1 and BG 2, respectively. Each of these CNs is connected to only a small number of BNs. The number of connected BNs to CN $i$ is $|\Bcal_i|$. In BG1 and BG2, $|\Bcal_i|=\{3,4,5,6,7,8,9,10,19\}$ and $|\Bcal_i|=\{3,4,5,6,8,10\}$, respectively. The following tables show the number of CNs $M_{|\Bcal_i|}$ that are connected to the same number of BNs.
-
-\begin{table}[ht]
- \centering
- \begin{tabular}{llllllllll}
- \toprule
- $|\Bcal_i|$ & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 19 \\
- \midrule
- $M_{|\Bcal_i|}^\mathrm{BG1}$ & 1 & 5 &18 & 8 & 5 & 2 & 2 & 1 & 4 \\
- $M_{|\Bcal_i|}^\mathrm{BG2}$ & 6 & 20 & 9 & 3 & 0 & 2 & 0 & 2 & 0 \\
- \bottomrule
- \end{tabular}
- \caption{Ceck node groups for BG1 and BG2.}
- \label{tab:checkNodeGroups}
-\end{table}
-
-It can be observed that each CN is at least connected to 3 BNs and there are 9 groups and 5 groups in BG1 and BG2, respectively. Denote the set of CN groups as $\Gcal$ and $M_k$ the number of CNs in group $k\in\Gcal$, e.g. for BG2 $M_4=20\Zc$. Each CN group will be processed separately. The CN processing buffer $p_C^k$ of group $k$ is defined as
-\begin{equation}
- \label{eq:44}
- p_C^k = \{\underbrace{q_{11}q_{21}\dots q_{M_k 1}}_{\text 1. BN},\underbrace{q_{12}q_{22}\dots q_{M_k 2}}_{\text 2. BN},\dots,\underbrace{q_{12}q_{22}\dots q_{M_k k}}_{\text last BN}\}
-\end{equation}
-Hence, $|p_C^k| = kM_k$, e.g, $\Zc=128$, $|p_C^4| = 4\cdot 20\cdot 128 = 10240$.
-
-\begin{lstlisting}[frame=single,caption={Example of CN processing for group 3 from \texttt{cnProc}.},label=code_cnproc] % Start your code-block
-
- const uint8_t lut_idxCnProcG3[3][2] = {{72,144}, {0,144}, {0,72}};
-
- // =====================================================================
- // Process group with 3 BNs
-
- // Number of groups of 32 CNs for parallel processing
- M = (lut_numCnInCnGroups[0]*Z)>>5;
- // Set the offset to each bit within a group in terms of 32 Byte
- bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX)>>5;
-
- // Set pointers to start of group 3
- p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[0]];
- p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[0]];
-
- // Loop over every BN
- for (j=0; j<3; j++)
- {
- // Set of results pointer to correct BN address
- p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
-
- // Loop over CNs
- for (i=0; i>5;
-
- // Set the offset to each CN within a group in terms of 16 Byte
- cnOffsetInGroup = (lut_numBnInBnGroups[2]*NR_LDPC_ZMAX)>>4;
-
- // Set pointers to start of group 3
- p_bnProcBuf = (__m128i*) &bnProcBuf [lut_startAddrBnGroups [idxBnGroup]];
- p_llrProcBuf = (__m128i*) &llrProcBuf [lut_startAddrBnGroupsLlr[idxBnGroup]];
- p_llrRes = (__m256i*) &llrRes [lut_startAddrBnGroupsLlr[idxBnGroup]];
-
- // Loop over BNs
- for (i=0,j=0; i ... \endif and \cond
-# ... \endcond blocks.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
-# initial value of a variable or macro / define can have for it to appear in the
-# documentation. If the initializer consists of more lines than specified here
-# it will be hidden. Use a value of 0 to hide initializers completely. The
-# appearance of the value of individual variables and macros / defines can be
-# controlled using \showinitializer or \hideinitializer command in the
-# documentation regardless of this setting.
-# Minimum value: 0, maximum value: 10000, default value: 30.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES, the
-# list will mention the files that were used to generate the documentation.
-# The default value is: YES.
-
-SHOW_USED_FILES = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
-# will remove the Files entry from the Quick Index and from the Folder Tree View
-# (if specified).
-# The default value is: YES.
-
-SHOW_FILES = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
-# page. This will remove the Namespaces entry from the Quick Index and from the
-# Folder Tree View (if specified).
-# The default value is: YES.
-
-SHOW_NAMESPACES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command command input-file, where command is the value of the
-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
-# by doxygen. Whatever the program writes to standard output is used as the file
-# version. For an example see the documentation.
-
-FILE_VERSION_FILTER =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option. You can
-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
-#
-# Note that if you run doxygen from a directory containing a file called
-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
-# tag is left empty.
-
-LAYOUT_FILE =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
-# the reference definitions. This must be a list of .bib files. The .bib
-# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
-# For LaTeX the style of the bibliography can be controlled using
-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. See also \cite for info how to create references.
-
-CITE_BIB_FILES =
-
-#---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated to
-# standard output by doxygen. If QUIET is set to YES this implies that the
-# messages are off.
-# The default value is: NO.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
-# this implies that the warnings are on.
-#
-# Tip: Turn warnings on while writing the documentation.
-# The default value is: YES.
-
-WARNINGS = YES
-
-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: YES.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
-# The default value is: YES.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
-# are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation.
-# The default value is: NO.
-
-WARN_NO_PARAMDOC = NO
-
-# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
-# a warning is encountered.
-# The default value is: NO.
-
-WARN_AS_ERROR = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
-# can produce. The string should contain the $file, $line, and $text tags, which
-# will be replaced by the file and line number from which the warning originated
-# and the warning text. Optionally the format may contain $version, which will
-# be replaced by the version of the file (if it could be obtained via
-# FILE_VERSION_FILTER)
-# The default value is: $file:$line: $text.
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
-# messages should be written. If left blank the output is written to standard
-# error (stderr).
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag is used to specify the files and/or directories that contain
-# documented source files. You may enter file names like myfile.cpp or
-# directories like /usr/src/myproject. Separate the files or directories with
-# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
-# Note: If this tag is empty the current directory is searched.
-
-INPUT = ../nrLDPC_defs.h ../nrLDPC_types.h ../nrLDPC_init.h ../nrLDPC_cnProc.h ../nrLDPC_bnProc.h ../nrLDPC_mPass.h ../nrLDPC_decoder.h ../nrLDPC_decoder.c ../nrLDPC_lut.h
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
-# possible encodings.
-# The default value is: UTF-8.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# read by doxygen.
-#
-# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
-# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
-# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
-
-FILE_PATTERNS =
-
-# The RECURSIVE tag can be used to specify whether or not subdirectories should
-# be searched for input files as well.
-# The default value is: NO.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-#
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-# The default value is: NO.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories for example use the pattern */test/*
-
-EXCLUDE_PATTERNS =
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories use the pattern */test/*
-
-EXCLUDE_SYMBOLS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
-# that contain example code fragments that are included (see the \include
-# command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank all
-# files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude commands
-# irrespective of the value of the RECURSIVE tag.
-# The default value is: NO.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or directories
-# that contain images that are to be included in the documentation (see the
-# \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command:
-#
-#
-#
-# where is the value of the INPUT_FILTER tag, and is the
-# name of an input file. Doxygen will then use the output that the filter
-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
-# will be ignored.
-#
-# Note that the filter must not add or remove lines; it is applied before the
-# code is scanned, but not when the output code is generated. If lines are added
-# or removed, the anchors will not be placed correctly.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form: pattern=filter
-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
-# patterns match the file name, INPUT_FILTER is applied.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will also be used to filter the input files that are used for
-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
-# The default value is: NO.
-
-FILTER_SOURCE_FILES = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
-# it is also possible to disable source filtering for a specific pattern using
-# *.ext= (so without naming a filter).
-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
-
-FILTER_SOURCE_PATTERNS =
-
-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page
-# (index.html). This can be useful if you have a project on for instance GitHub
-# and want to reuse the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
-# generated. Documented entities will be cross-referenced with these sources.
-#
-# Note: To get rid of all source code in the generated output, make sure that
-# also VERBATIM_HEADERS is set to NO.
-# The default value is: NO.
-
-SOURCE_BROWSER = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
-# classes and enums directly into the documentation.
-# The default value is: NO.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
-# special comment blocks from generated source code fragments. Normal C, C++ and
-# Fortran comments will always remain visible.
-# The default value is: YES.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# function all documented functions referencing it will be listed.
-# The default value is: NO.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES then for each documented function
-# all documented entities called/used by that function will be listed.
-# The default value is: NO.
-
-REFERENCES_RELATION = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
-# link to the documentation.
-# The default value is: YES.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
-# source code will show a tooltip with additional information such as prototype,
-# brief description and links to the definition and documentation. Since this
-# will make the HTML file larger and loading of large files a bit slower, you
-# can opt to disable this feature.
-# The default value is: YES.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-SOURCE_TOOLTIPS = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code will
-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
-# source browser. The htags tool is part of GNU's global source tagging system
-# (see http://www.gnu.org/software/global/global.html). You will need version
-# 4.8.6 or higher.
-#
-# To use it do the following:
-# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
-# - Make sure the INPUT points to the root of the source tree
-# - Run doxygen as normal
-#
-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
-# tools must be available from the command line (i.e. in the search path).
-#
-# The result: instead of the source browser generated by doxygen, the links to
-# source code will now point to the output of htags.
-# The default value is: NO.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
-# verbatim copy of the header file for each class for which an include is
-# specified. Set to NO to disable this.
-# See also: Section \class.
-# The default value is: YES.
-
-VERBATIM_HEADERS = YES
-
-# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
-# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
-# cost of reduced performance. This can be particularly helpful with template
-# rich C++ code for which doxygen's built-in parser lacks the necessary type
-# information.
-# Note: The availability of this option depends on whether or not doxygen was
-# generated with the -Duse-libclang=ON option for CMake.
-# The default value is: NO.
-
-CLANG_ASSISTED_PARSING = NO
-
-# If clang assisted parsing is enabled you can provide the compiler with command
-# line options that you would normally use when invoking the compiler. Note that
-# the include paths will already be set by doxygen for the files and directories
-# specified with INPUT and INCLUDE_PATH.
-# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
-
-CLANG_OPTIONS =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
-# compounds will be generated. Enable this if the project contains a lot of
-# classes, structs, unions or interfaces.
-# The default value is: YES.
-
-ALPHABETICAL_INDEX = YES
-
-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
-# which the alphabetical index list will be split.
-# Minimum value: 1, maximum value: 20, default value: 5.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all classes will
-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
-# can be used to specify a prefix (or a list of prefixes) that should be ignored
-# while generating the index headers.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
-# The default value is: YES.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
-# generated HTML page (for example: .htm, .php, .asp).
-# The default value is: .html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
-# each generated HTML page. If the tag is left blank doxygen will generate a
-# standard header.
-#
-# To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used (e.g.
-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
-# default header using
-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
-# YourConfigFile
-# and then modify the file new_header.html. See also section "Doxygen usage"
-# for information on how to generate the default header that doxygen normally
-# uses.
-# Note: The header is subject to change so you typically have to regenerate the
-# default header when upgrading to a newer version of doxygen. For a description
-# of the possible markers and block names see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
-# generated HTML page. If the tag is left blank doxygen will generate a standard
-# footer. See HTML_HEADER for more information on how to generate a default
-# footer and what special commands can be used inside the footer. See also
-# section "Doxygen usage" for information on how to generate the default footer
-# that doxygen normally uses.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
-# sheet that is used by each HTML page. It can be used to fine-tune the look of
-# the HTML output. If left blank doxygen will generate a default style sheet.
-# See also section "Doxygen usage" for information on how to generate the style
-# sheet that doxygen normally uses.
-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
-# obsolete.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_STYLESHEET =
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# cascading style sheets that are included after the standard style sheets
-# created by doxygen. Using this option one can overrule certain style aspects.
-# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefore more robust against future updates.
-# Doxygen will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list). For an example see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_STYLESHEET =
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
-# files will be copied as-is; there are no commands or markers available.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_FILES =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the style sheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
-# purple, and 360 is red again.
-# Minimum value: 0, maximum value: 359, default value: 220.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_HUE = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
-# value of 255 will produce the most vivid colors.
-# Minimum value: 0, maximum value: 255, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_SAT = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
-# luminance component of the colors in the HTML output. Values below 100
-# gradually make the output lighter, whereas values above 100 make the output
-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
-# change the gamma.
-# Minimum value: 40, maximum value: 240, default value: 80.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_GAMMA = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting this
-# to YES can help to show when doxygen was last run and thus if the
-# documentation is up to date.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_TIMESTAMP = NO
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_SECTIONS = NO
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
-# shown in the various tree structured indices initially; the user can expand
-# and collapse entries dynamically later on. Doxygen will expand the tree to
-# such a level that at most the specified number of entries are visible (unless
-# a fully collapsed tree already exceeds this amount). So setting the number of
-# entries 1 will produce a full collapsed tree by default. 0 is a special value
-# representing an infinite number of entries and will result in a full expanded
-# tree by default.
-# Minimum value: 0, maximum value: 9999, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
-# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_DOCSET = NO
-
-# This tag determines the name of the docset feed. A documentation feed provides
-# an umbrella under which multiple documentation sets from a single provider
-# (such as a company or product suite) can be grouped.
-# The default value is: Doxygen generated docs.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# This tag specifies a string that should uniquely identify the documentation
-# set bundle. This should be a reverse domain-name style string, e.g.
-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-# The default value is: org.doxygen.Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-
-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
-# The default value is: Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_NAME = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
-#
-# The HTML Help Workshop contains a compiler that can convert all HTML output
-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
-# files are now used as the Windows 98 help format, and will replace the old
-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
-# HTML files also contain an index, a table of contents, and you can search for
-# words in the documentation. The HTML workshop also contains a viewer for
-# compressed HTML files.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_HTMLHELP = NO
-
-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
-# file. You can add a path in front of the file if the result should not be
-# written to the html output directory.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_FILE =
-
-# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
-# doxygen will try to run the HTML help compiler on the generated index.hhp.
-# The file has to be specified with full path.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-HHC_LOCATION =
-
-# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-GENERATE_CHI = NO
-
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
-# and project file content.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_INDEX_ENCODING =
-
-# The BINARY_TOC flag controls whether a binary table of contents is generated
-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
-# enables the Previous and Next buttons.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
-# the table of contents of the HTML help documentation and to the tree view.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-TOC_EXPAND = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
-# (.qch) of the generated HTML documentation.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
-# the file name of the resulting .qch file. The path specified is relative to
-# the HTML output folder.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QCH_FILE =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
-# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_NAMESPACE = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
-# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
-# folders).
-# The default value is: doc.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
-# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_NAME =
-
-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_ATTRS =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_SECT_FILTER_ATTRS =
-
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHG_LOCATION =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
-# generated, together with the HTML files, they form an Eclipse help plugin. To
-# install this plugin and make it available under the help contents menu in
-# Eclipse, the contents of the directory containing the HTML and XML files needs
-# to be copied into the plugins directory of eclipse. The name of the directory
-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
-# After copying Eclipse needs to be restarted before the help appears.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_ECLIPSEHELP = NO
-
-# A unique identifier for the Eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have this
-# name. Each documentation set should have its own identifier.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
-
-ECLIPSE_DOC_ID = org.doxygen.Project
-
-# If you want full control over the layout of the generated HTML pages it might
-# be necessary to disable the index and replace it with your own. The
-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
-# of each HTML page. A value of NO enables the index and the value YES disables
-# it. Since the tabs in the index contain the same information as the navigation
-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-DISABLE_INDEX = NO
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information. If the tag
-# value is set to YES, a side panel will be generated containing a tree-like
-# index structure (just like the one that is generated for HTML Help). For this
-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
-# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_TREEVIEW = NO
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
-# doxygen will group on one line in the generated HTML documentation.
-#
-# Note that a value of 0 will completely suppress the enum values from appearing
-# in the overview section.
-# Minimum value: 0, maximum value: 20, default value: 4.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
-# to set the initial width (in pixels) of the frame in which the tree is shown.
-# Minimum value: 0, maximum value: 1500, default value: 250.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-TREEVIEW_WIDTH = 250
-
-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
-# external symbols imported via tag files in a separate window.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-EXT_LINKS_IN_WINDOW = NO
-
-# Use this tag to change the font size of LaTeX formulas included as images in
-# the HTML documentation. When you change the font size after a successful
-# doxygen run you need to manually remove any form_*.png images from the HTML
-# output directory to force them to be regenerated.
-# Minimum value: 8, maximum value: 50, default value: 10.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_FONTSIZE = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are not
-# supported properly for IE 6.0, but are supported on all modern browsers.
-#
-# Note that when changing this option you need to delete any form_*.png files in
-# the HTML output directory before the changes have effect.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_TRANSPARENT = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
-# installed or if you want to formulas look prettier in the HTML output. When
-# enabled you may also need to install MathJax separately and configure the path
-# to it using the MATHJAX_RELPATH option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-USE_MATHJAX = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
-# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
-# The default value is: HTML-CSS.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_FORMAT = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the HTML
-# output directory using the MATHJAX_RELPATH option. The destination directory
-# should contain the MathJax.js script. For instance, if the mathjax directory
-# is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
-# Content Delivery Network so you can quickly see the result without installing
-# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
-# extension names that should be enabled during MathJax rendering. For example
-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_EXTENSIONS =
-
-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
-# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
-# example see the documentation.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_CODEFILE =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
-# the HTML output. The underlying search engine uses javascript and DHTML and
-# should work on any modern browser. Note that when using HTML help
-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
-# there is already a search function so this one should typically be disabled.
-# For large projects the javascript based search engine can be slow, then
-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
-# search using the keyboard; to jump to the search box use + S
-# (what the is depends on the OS and browser, but it is typically
-# , /