Merge branch 'integration_2024_w42' into 'develop'
Integration: `2024.w42` Closes #547, #853, #854, #858, #859, #862, #844, and #746 See merge request oai/openairinterface5g!3053 * !3047 Resolve compilation warnings on ARM * !3052 Optimize T_ID() macro. * !3045 CI: Reduce tested DL throughput on Aerial * !3039 fix for Other SI reception when BWP start != 0 * !2997 websrv regression * !3041 Update NR SA Tutorials * !3042 Update TESTBenches.md to reflect current testbench * !3004 Hotfix to remove an unwanted TX power reduction when using multiple TX antenna ports. * reduce ssPBCH_BlockPower in gNB config of FHI7.2 pipeline * !3046 A testsuite and a benchmark for RLC AM mode * !3038 Various bugfixes for gNB stability, cleanup * !3051 PUCCH2 DTX detection * nr_psbchsim: fix segv by providing correct get_nrUE_params() * !3049 Improve PUSCH and PUCCH SNR stability * !3054 Allocate and add sD to DRB NSSAI in case sD != 0xffffff
This commit is contained in:
@@ -1260,7 +1260,6 @@ set(L2_NR_SRC
|
||||
${NR_PDCP_SRC}
|
||||
${NR_SDAP_SRC}
|
||||
${NR_RRC_DIR}/rrc_gNB.c
|
||||
${NR_RRC_DIR}/nr_rrc_common.c
|
||||
${NR_RRC_DIR}/mac_rrc_dl_direct.c
|
||||
${NR_RRC_DIR}/mac_rrc_dl_f1ap.c
|
||||
${NR_RRC_DIR}/nr_rrc_config.c
|
||||
|
||||
@@ -152,7 +152,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -10;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
<testCase id="000022">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/UDP/700M)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 700M -t 30 -R</iperf_args>
|
||||
<iperf_args>-u -b 600M -t 30 -R</iperf_args>
|
||||
<svr_id>porcepix-cn5g</svr_id>
|
||||
<id>up2-aerial</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
|
||||
@@ -330,7 +330,7 @@
|
||||
-R 273 -z8 -i 1 -P 0 -b 1 -s-2 -n1000
|
||||
-R 273 -z8 -i 1 -P 0 -b 2 -s-2 -n1000
|
||||
-R 273 -z8 -i 1 -P 0 -b 2 -s-2 -c -n1000
|
||||
-R 273 -z8 -i 1 -P 2 -b 4 -s0 -n1000
|
||||
-R 273 -z8 -i 1 -P 2 -b 4 -s-10 -n1000
|
||||
-R 273 -z8 -i 1 -P 2 -b 7 -s3 -n1000
|
||||
-R 273 -z8 -i 1 -P 2 -b 11 -s6 -n1000
|
||||
-R 273 -z8 -i 1 -P 2 -q8 -b 12 -s-3 -n1000
|
||||
|
||||
@@ -4,6 +4,8 @@ set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc-11)
|
||||
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++-11)
|
||||
|
||||
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/aarch64-linux-gnu/pkgconfig")
|
||||
|
||||
set(CROSS_COMPILE 1)
|
||||
set(bnProc_gen_128_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NATIVE_DIR}) # /../build)
|
||||
set(bnProc_gen_avx2_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NATIVE_DIR}) # /../build)
|
||||
|
||||
@@ -92,7 +92,11 @@
|
||||
struct T_header;
|
||||
|
||||
/* to define message ID */
|
||||
#ifdef CHECK_T_TYPE
|
||||
#define T_ID(x) ((struct T_header *)(uintptr_t)(x))
|
||||
#else
|
||||
#define T_ID(x) x
|
||||
#endif
|
||||
|
||||
/* T macro tricks */
|
||||
extern int T_stdout;
|
||||
|
||||
@@ -68,9 +68,9 @@ static int get_single_ue_id(void)
|
||||
* @param prnt: Print function
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int rrc_gNB_trigger_release(char *buf, int debug, telnet_printfunc_t prnt) {
|
||||
int rrc_gNB_trigger_release(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
ue_id_t ue_id = -1;
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
if (!buf) {
|
||||
ue_id = get_single_ue_id();
|
||||
@@ -96,10 +96,8 @@ int rrc_gNB_trigger_release(char *buf, int debug, telnet_printfunc_t prnt) {
|
||||
}
|
||||
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
|
||||
ctxt.eNB_index = 0;
|
||||
|
||||
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
|
||||
rrc_gNB_generate_RRCRelease(rrc, UE);
|
||||
prnt("RRC Release triggered for UE %u\n", ue_id);
|
||||
|
||||
return 0;
|
||||
@@ -108,16 +106,14 @@ int rrc_gNB_trigger_release(char *buf, int debug, telnet_printfunc_t prnt) {
|
||||
/**
|
||||
* @brief Trigger RRC Release for all UEs
|
||||
*/
|
||||
int rrc_gNB_trigger_release_all(char *buf, int debug, telnet_printfunc_t prnt) {
|
||||
int rrc_gNB_trigger_release_all(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
protocol_ctxt_t ctxt; /* Not sure what exactly is this */
|
||||
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[0]->rrc_ue_head)) {
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc->rrc_ue_head) {
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
|
||||
ctxt.eNB_index = 0;
|
||||
|
||||
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
|
||||
rrc_gNB_generate_RRCRelease(rrc, UE);
|
||||
prnt("RRC Release triggered for UE %u\n", UE->rrc_ue_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,8 @@
|
||||
extern int cpu_meas_enabled;
|
||||
extern double cpu_freq_GHz __attribute__ ((aligned(32)));;
|
||||
// structure to store data to compute cpu measurment
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
|
||||
typedef long long oai_cputime_t;
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
typedef uint32_t oai_cputime_t;
|
||||
#else
|
||||
#error "building on unsupported CPU architecture"
|
||||
#endif
|
||||
|
||||
@@ -62,7 +62,7 @@ add_library(websrv MODULE
|
||||
websrv_utils.c
|
||||
../../../openair1/PHY/TOOLS/nr_phy_scope.c
|
||||
)
|
||||
target_link_libraries(websrv PRIVATE ulfius jansson)
|
||||
target_link_libraries(websrv PRIVATE ulfius jansson asn1_nr_rrc_hdrs)
|
||||
target_compile_definitions(websrv PUBLIC WEBSRVSCOPE)
|
||||
# put websrv into build root and not under build/common/utils/websrv/
|
||||
set_target_properties(websrv PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../../..)
|
||||
|
||||
@@ -38,6 +38,20 @@ $ sudo dnf install -y jansson-devel npm curl wget
|
||||
|
||||
ulfius has to be installed as explained [here](https://github.com/babelouest/ulfius/blob/master/INSTALL.md#pre-compiled-packages).
|
||||
|
||||
## Install from source if needed
|
||||
|
||||
```bash
|
||||
sudo dnf install -y jansson-devel npm curl wget libmicrohttpd-devel curl curlpp-devel systemd-devel
|
||||
git clone https://github.com/babelouest/orcania.git
|
||||
cd orcania; mkdir build; cd build; cmake ..; sudo make install
|
||||
cd
|
||||
git clone https://github.com/babelouest/yder.git
|
||||
cd yder ; mkdir build; cd build; cmake ..; sudo make install
|
||||
git clone https://github.com/babelouest/ulfius.git
|
||||
cd ulfius
|
||||
mkdir build; cd build; cmake ..; sudo make install
|
||||
```
|
||||
|
||||
## Additional dependencies for the frontend
|
||||
|
||||
Currently the web server frontend can run with nodejs 18, you can check the
|
||||
@@ -54,6 +68,16 @@ beyond this doc.
|
||||
|
||||
For example, to install a specific nodeJS version, you can run the below
|
||||
command, with the typical output printed below for your convenience:
|
||||
|
||||
install method by nvm
|
||||
```bash
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
|
||||
source ~/.bashrc
|
||||
nvm install 18
|
||||
nvm use 18
|
||||
```
|
||||
|
||||
install by apt-get
|
||||
```bash
|
||||
$ curl -s https://deb.nodesource.com/setup_18.x | sudo bash
|
||||
|
||||
|
||||
@@ -1886,13 +1886,11 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_radio_bearers.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_NGAP.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/nr_rrc_proto.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/nr_rrc_common.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_UE_context.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/MESSAGES/asn1_msg.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/MESSAGES/asn1_msg.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_UE_context.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/cucp_cuup_e1ap.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/nr_rrc_common.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/nr_rrc_config.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_radio_bearers.h \
|
||||
|
||||
@@ -21,7 +21,7 @@ In this tutorial we describe how to configure and run a 5G end-to-end setup with
|
||||
|
||||
Minimum hardware requirements:
|
||||
- Laptop/Desktop/Server for OAI CN5G and OAI gNB
|
||||
- Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.4-desktop-amd64.iso)
|
||||
- Operating System: [Ubuntu 24.04 LTS](https://releases.ubuntu.com/24.04/ubuntu-24.04.1-desktop-amd64.iso)
|
||||
- CPU: 8 cores x86_64 @ 3.5 GHz
|
||||
- RAM: 32 GB
|
||||
- Laptop for UE
|
||||
@@ -59,11 +59,11 @@ sudo ./program_uicc --adm 12345678 --imsi 001010000000001 --isdn 00000001 --acc
|
||||
### Build UHD from source
|
||||
```bash
|
||||
# https://files.ettus.com/manual/page_build_guide.html
|
||||
sudo apt install -y autoconf automake build-essential ccache cmake cpufrequtils doxygen ethtool g++ git inetutils-tools libboost-all-dev libncurses5 libncurses5-dev libusb-1.0-0 libusb-1.0-0-dev libusb-dev python3-dev python3-mako python3-numpy python3-requests python3-scipy python3-setuptools python3-ruamel.yaml
|
||||
sudo apt install -y autoconf automake build-essential ccache cmake cpufrequtils doxygen ethtool g++ git inetutils-tools libboost-all-dev libncurses-dev libusb-1.0-0 libusb-1.0-0-dev libusb-dev python3-dev python3-mako python3-numpy python3-requests python3-scipy python3-setuptools python3-ruamel.yaml
|
||||
|
||||
git clone https://github.com/EttusResearch/uhd.git ~/uhd
|
||||
cd ~/uhd
|
||||
git checkout v4.6.0.0
|
||||
git checkout v4.7.0.0
|
||||
cd host
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
@@ -21,7 +21,7 @@ In this tutorial we describe how to configure and run a 5G end-to-end setup with
|
||||
|
||||
Minimum hardware requirements:
|
||||
- Laptop/Desktop/Server for OAI CN5G and OAI gNB
|
||||
- Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.4-desktop-amd64.iso)
|
||||
- Operating System: [Ubuntu 24.04 LTS](https://releases.ubuntu.com/24.04/ubuntu-24.04.1-desktop-amd64.iso)
|
||||
- CPU: 8 cores x86_64 @ 3.5 GHz
|
||||
- RAM: 32 GB
|
||||
|
||||
@@ -33,11 +33,12 @@ Minimum hardware requirements:
|
||||
sudo apt install -y git net-tools putty
|
||||
|
||||
# https://docs.docker.com/engine/install/ubuntu/
|
||||
sudo apt install -y ca-certificates curl gnupg
|
||||
sudo apt update
|
||||
sudo apt install -y ca-certificates curl
|
||||
sudo install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
sudo chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
sudo apt update
|
||||
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ In this tutorial we describe how to configure and run a 5G end-to-end setup with
|
||||
|
||||
Minimum hardware requirements:
|
||||
- Laptop/Desktop/Server for OAI CN5G and OAI gNB
|
||||
- Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.4-desktop-amd64.iso)
|
||||
- Operating System: [Ubuntu 24.04 LTS](https://releases.ubuntu.com/24.04/ubuntu-24.04.1-desktop-amd64.iso)
|
||||
- CPU: 8 cores x86_64 @ 3.5 GHz
|
||||
- RAM: 32 GB
|
||||
- Laptop for UE
|
||||
- Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.4-desktop-amd64.iso)
|
||||
- Operating System: [Ubuntu 24.04 LTS](https://releases.ubuntu.com/24.04/ubuntu-24.04.1-desktop-amd64.iso)
|
||||
- CPU: 8 cores x86_64 @ 3.5 GHz
|
||||
- RAM: 8 GB
|
||||
- [USRP B210](https://www.ettus.com/all-products/ub210-kit/), [USRP N300](https://www.ettus.com/all-products/USRP-N300/) or [USRP X300](https://www.ettus.com/all-products/x300-kit/)
|
||||
@@ -47,11 +47,11 @@ Please install and configure OAI CN5G as described here:
|
||||
### Build UHD from source
|
||||
```bash
|
||||
# https://files.ettus.com/manual/page_build_guide.html
|
||||
sudo apt install -y autoconf automake build-essential ccache cmake cpufrequtils doxygen ethtool g++ git inetutils-tools libboost-all-dev libncurses5 libncurses5-dev libusb-1.0-0 libusb-1.0-0-dev libusb-dev python3-dev python3-mako python3-numpy python3-requests python3-scipy python3-setuptools python3-ruamel.yaml
|
||||
sudo apt install -y autoconf automake build-essential ccache cmake cpufrequtils doxygen ethtool g++ git inetutils-tools libboost-all-dev libncurses-dev libusb-1.0-0 libusb-1.0-0-dev libusb-dev python3-dev python3-mako python3-numpy python3-requests python3-scipy python3-setuptools python3-ruamel.yaml
|
||||
|
||||
git clone https://github.com/EttusResearch/uhd.git ~/uhd
|
||||
cd ~/uhd
|
||||
git checkout v4.6.0.0
|
||||
git checkout v4.7.0.0
|
||||
cd host
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
+6
-11
@@ -23,7 +23,7 @@
|
||||
| avra | 172.21.16.124 | CI-Avra-Usage | gNB (n78) | AW2S Jaguar (192.168.80.239) |
|
||||
| orion | 172.21.16.134 | CI-Orion-Build-Sanity-Check-Deploy-Test, CI-Orion-DsTester-Deploy-Test | Build | |
|
||||
| aerial2 | 172.21.16.131 | CI-Aerial2-Usage | gNB (PNF/Nvidia CUBB + VNF) | Foxconn RU, _Nvidia Aerial SDK integrated_ |
|
||||
| sphex | 172.21.17.54 | CI-Sphex-Usage | COTS UE | Quectel RM520N |
|
||||
| cacofonix | 172.21.16.150 | CI-Cacofonix-Usage | gNB (n78, FHI7.2) | |
|
||||
| matix | 172.21.19.58 | CI-Matix-Usage | gNB (n77) | N310 |
|
||||
|
||||
Note: The available resources, and their current usage, is indicated here:
|
||||
@@ -141,10 +141,6 @@ information on how the images are built.
|
||||
~4G-LTE
|
||||
- obelix (eNB, 1x UE, OAI EPC)
|
||||
- L2simulator: skips physical layer and uses proxy between eNB and UE
|
||||
- [RAN-L2-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-5G/)
|
||||
~5G-NR
|
||||
- obelix (gNB, 1x UE, OAI 5GC)
|
||||
- L2simulator: skips physical layer and uses proxy between gNB and UE, currently only ping
|
||||
- [RAN-LTE-FDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-FDD-LTEBOX-Container/)
|
||||
~4G-LTE
|
||||
- hutch + B210, nano w/ ltebox + 2x UE
|
||||
@@ -172,15 +168,15 @@ information on how the images are built.
|
||||
- see [`./physical-simulators.md`](./physical-simulators.md) for an overview
|
||||
- [RAN-RF-Sim-Test-4G](https://jenkins-oai.eurecom.fr/job/RAN-RF-Sim-Test-4G/)
|
||||
~4G-LTE
|
||||
- obelix (eNB, lteUE, OAI EPC)
|
||||
- cacofonix (eNB, lteUE, OAI EPC)
|
||||
- uses RFsimulator, for FDD 5, 10, 20MHz with core, 5MHz noS1
|
||||
- [RAN-RF-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-RF-Sim-Test-5G/)
|
||||
~5G-NR
|
||||
- obelix (gNB, nrUE, OAI 5GC)
|
||||
- cacofonix (gNB, nrUE, OAI 5GC)
|
||||
- uses RFsimulator, TDD 40MHz, FDD 40MHz, F1 split
|
||||
- [RAN-SA-AW2S-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AW2S-CN5G/)
|
||||
~5G-NR
|
||||
- 5G-NR SA test setup: avra(RHEL9.1) + AW2S, amariue, OAI CN5G
|
||||
- 5G-NR SA test setup: avra + AW2S, amariue, OAI CN5G
|
||||
- uses OpenShift cluster for CN deployment and container images for gNB deployment
|
||||
- multi UE testing using Amarisoft UE simulator
|
||||
- [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/)
|
||||
@@ -189,11 +185,11 @@ information on how the images are built.
|
||||
- basic SA test (20 MHz TDD), F1, reestablishment, ...
|
||||
- [RAN-SA-OAIUE-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-OAIUE-CN5G/)
|
||||
~5G-NR
|
||||
- 5G-NR SA test setup: gNB on avra(RHEL9.2) + N310, OAIUE on caracal(RHEL9.1) + N310, OAI CN5G
|
||||
- 5G-NR SA test setup: gNB on avra + N310, OAIUE on caracal + N310, OAI CN5G
|
||||
- OpenShift cluster for CN deployment and container images for gNB and UE deployment
|
||||
- [RAN-SA-AERIAL-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-CN5G/)
|
||||
~5G-NR
|
||||
- 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on Aerial2 (U22) + Foxconn RU, up2 + COTS UE (Quectel RM520N), OAI CN5G
|
||||
- 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on Aerial2 + Foxconn RU, up2 + COTS UE (Quectel RM520N), OAI CN5G
|
||||
- container images for gNB deployment
|
||||
- [RAN-SA-2x2-Module-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-2x2-Module-CN5G/)
|
||||
~5G-NR
|
||||
@@ -201,7 +197,6 @@ information on how the images are built.
|
||||
- NR performance tests: 2x2 configuration, 60 MHz and 100 MHz bandwidth
|
||||
- [RAN-SA-FHI72-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-FHI72-CN5G/)
|
||||
~5G-NR
|
||||
- cacofonix + FHI72 + Benetel550 (gNB), AmariUE, OAI CN5G
|
||||
- cacofonix + FHI72 + VVDN (gNB), up2 (Quectel RM520N UE), OAI CN5G
|
||||
- OpenShift cluster for CN deployment
|
||||
- FHI 7.2 testing with 100 MHz bandwidth, 2 layers in DL
|
||||
|
||||
@@ -43,7 +43,9 @@ RUN /bin/sh oaienv && \
|
||||
cd ../build-cross/ && \
|
||||
# install missing libyaml-cpp-dev for arm64
|
||||
apt install -y libyaml-cpp-dev:arm64 && \
|
||||
cmake ../../.. -GNinja -DCMAKE_TOOLCHAIN_FILE=../../../cmake_targets/cross-arm.cmake -DNATIVE_DIR=../build && \
|
||||
cmake ../../.. -GNinja \
|
||||
-DCMAKE_TOOLCHAIN_FILE=../../../cmake_targets/cross-arm.cmake -DNATIVE_DIR=../build \
|
||||
-DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror" && \
|
||||
echo "====== Start of log for cross-build executables ======" && \
|
||||
# making always passing so we can analyze the all.txt file
|
||||
ninja dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim lte-softmodem nr-softmodem nr-cuup oairu lte-uesoftmodem nr-uesoftmodem params_libconfig coding rfsimulator > ../../log/all.txt 2>&1; \
|
||||
|
||||
@@ -123,11 +123,6 @@ int nr_rlc_get_available_tx_space(const rnti_t rntiP, const logical_chan_id_t ch
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
||||
{
|
||||
abort();
|
||||
|
||||
@@ -8010,12 +8010,12 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
|
||||
(int32_t *) rho_256i,
|
||||
len);
|
||||
#else // defined(__arm__) || defined(__aarch64__)
|
||||
qam64_qam64((int32_t *)rxF_256i,
|
||||
(int32_t *)rxF_i_256i,
|
||||
(int32_t *)ch_mag_256i,
|
||||
(int32_t *)ch_mag_i_256i,
|
||||
(int16_t *)llr16,
|
||||
(int32_t *) rho_256i,
|
||||
qam64_qam64((short *)rxF_256i,
|
||||
(short *)rxF_i_256i,
|
||||
(short *)ch_mag_256i,
|
||||
(short *)ch_mag_i_256i,
|
||||
(short *)llr16,
|
||||
(short *) rho_256i,
|
||||
len);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
|
||||
signal_energy = signal_energy_nodc(ul_ch, 12);
|
||||
}
|
||||
n0_subband_power[aarx][rb] += signal_energy;
|
||||
LOG_D(PHY,"slot %d symbol %d RB %d aarx %d n0_subband_power %d\n", slot, s, rb, aarx, signal_energy);
|
||||
LOG_D(NR_PHY,"slot %d symbol %d RB %d aarx %d n0_subband_power %d\n", slot, s, rb, aarx, signal_energy);
|
||||
} //antenna
|
||||
}
|
||||
} //rb
|
||||
@@ -177,7 +177,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
|
||||
n0_subband_tot_perPRB/=frame_parms->nb_antennas_rx;
|
||||
measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_subband_tot_perPRB);
|
||||
measurements->n0_subband_power_tot_dBm[rb] = measurements->n0_subband_power_tot_dB[rb] - gNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL);
|
||||
LOG_D(PHY,"n0_subband_power_tot_dB[%d] => %d, over %d symbols\n",rb,measurements->n0_subband_power_tot_dB[rb],nb_symb[rb]);
|
||||
LOG_D(NR_PHY,"n0_subband_power_tot_dB[%d] => %d, over %d symbols\n",rb,measurements->n0_subband_power_tot_dB[rb],nb_symb[rb]);
|
||||
n0_subband_tot += n0_subband_tot_perPRB;
|
||||
nb_rb++;
|
||||
}
|
||||
|
||||
@@ -1087,7 +1087,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
pucch2_lev += signal_energy_nodc(rp[aa][symb], nb_re_pucch);
|
||||
}
|
||||
}
|
||||
pucch2_lev /= Prx * Prx * pucch_pdu->nr_of_symbols;
|
||||
|
||||
pucch2_lev /= Prx * pucch_pdu->nr_of_symbols;
|
||||
int pucch2_levdB = dB_fixed(pucch2_lev);
|
||||
int scaling = 0;
|
||||
if (pucch2_levdB > 72)
|
||||
@@ -1099,7 +1100,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
else if (pucch2_levdB > 54)
|
||||
scaling = 1;
|
||||
|
||||
LOG_D(PHY,
|
||||
LOG_D(NR_PHY,
|
||||
"%d.%d Decoding pucch2 for %d symbols, %d PRB, nb_harq %d, nb_sr %d, nb_csi %d/%d, pucch2_lev %d dB (scaling %d)\n",
|
||||
frame,
|
||||
slot,
|
||||
@@ -1365,8 +1366,11 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
|
||||
uint64_t decodedPayload[2];
|
||||
uint8_t corr_dB;
|
||||
int decoderState=2;
|
||||
if (nb_bit < 12) { // short blocklength case
|
||||
int decoderState = 2;
|
||||
if (pucch2_levdB < gNB->measurements.n0_subband_power_avg_dB + (gNB->pucch0_thres / 10))
|
||||
decoderState = 1; // assuming missed detection, only attempt to decode for polar case (with CRC)
|
||||
LOG_D(NR_PHY, "n0+thres %d decoderState %d\n", gNB->measurements.n0_subband_power_avg_dB + (gNB->pucch0_thres / 10), decoderState);
|
||||
if (nb_bit < 12 && decoderState == 2) { // short blocklength case
|
||||
simde__m256i *rp_re[Prx2][2];
|
||||
simde__m256i *rp2_re[Prx2][2];
|
||||
simde__m256i *rp_im[Prx2][2];
|
||||
@@ -1382,8 +1386,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
simde__m256i prod_re[Prx2],prod_im[Prx2];
|
||||
uint64_t corr=0;
|
||||
int cw_ML=0;
|
||||
|
||||
|
||||
|
||||
for (int cw=0;cw<1<<nb_bit;cw++) {
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("cw %d:",cw);
|
||||
@@ -1485,9 +1488,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
printf("slot %d PUCCH2 cw_ML %d, metric %d \n",slot,cw_ML,corr_dB);
|
||||
#endif
|
||||
decodedPayload[0]=(uint64_t)cw_ML;
|
||||
}
|
||||
else { // polar coded case
|
||||
|
||||
} else if (nb_bit >= 12) { // polar coded case
|
||||
simde__m64 *rp_re[Prx2][2];
|
||||
simde__m64 *rp2_re[Prx2][2];
|
||||
simde__m64 *rp_im[Prx2][2];
|
||||
|
||||
@@ -1549,7 +1549,7 @@ void dft512(int16_t *x,int16_t *y,unsigned char scale)
|
||||
{
|
||||
|
||||
simdshort_q15_t xtmp[256],*xtmpp,*x64 = (simdshort_q15_t *)x;
|
||||
simd_q15_t ytmp[128],*tw512_128p=(simd_q15_t*)tw512,*tw512a_128p=(simd_q15_t *)tw512a,*tw512b_128p=(simd_q15_t *)tw512b,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
|
||||
simd_q15_t ytmp[128],*tw512a_128p=(simd_q15_t *)tw512a,*tw512b_128p=(simd_q15_t *)tw512b,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
|
||||
simd_q15_t *ytmpp = &ytmp[0];
|
||||
int i;
|
||||
simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
@@ -25,6 +45,7 @@
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "NR_SL-SSB-TimeAllocation-r16.h"
|
||||
#include "nr-uesoftmodem.h"
|
||||
|
||||
void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
||||
{
|
||||
@@ -54,12 +75,13 @@ double cpuf;
|
||||
void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, uint8_t *nb_dmrs_re_per_rb, uint16_t *number_dmrs_symbols)
|
||||
{
|
||||
}
|
||||
uint64_t downlink_frequency[1][1];
|
||||
int32_t uplink_frequency_offset[1][1];
|
||||
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
THREAD_STRUCT thread_struct;
|
||||
instance_t DUuniqInstance = 0;
|
||||
instance_t CUuniqInstance = 0;
|
||||
openair0_config_t openair0_cfg[1];
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
RAN_CONTEXT_t RC;
|
||||
int oai_exit = 0;
|
||||
@@ -80,9 +102,11 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void get_nrUE_params(void)
|
||||
nrUE_params_t nrUE_params = {0};
|
||||
|
||||
nrUE_params_t *get_nrUE_params(void)
|
||||
{
|
||||
return;
|
||||
return &nrUE_params;
|
||||
}
|
||||
uint8_t check_if_ue_is_sl_syncsource()
|
||||
{
|
||||
|
||||
@@ -145,7 +145,7 @@ int main(int argc, char **argv)
|
||||
//unsigned char frame_type = 0;
|
||||
int loglvl=OAILOG_WARNING;
|
||||
int sr_flag = 0;
|
||||
int pucch_DTX_thres = 50;
|
||||
int pucch_DTX_thres = 0;
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
|
||||
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) {
|
||||
|
||||
@@ -108,8 +108,12 @@ static void f1ap_write_drb_nssai(const nssai_t *nssai, F1AP_SNSSAI_t *asn1_nssai
|
||||
OCTET_STRING_fromBuf(&asn1_nssai->sST, (char *)&nssai->sst, 1);
|
||||
|
||||
/* OPTIONAL */
|
||||
if (nssai->sd != 0xffffff)
|
||||
OCTET_STRING_fromBuf(asn1_nssai->sD, (char *)&nssai->sd, 3);
|
||||
if (nssai->sd != 0xffffff) {
|
||||
char sd_buffer[3];
|
||||
INT24_TO_BUFFER(nssai->sd, sd_buffer);
|
||||
asn1cCalloc(asn1_nssai->sD, sD);
|
||||
OCTET_STRING_fromBuf(sD, sd_buffer, 3);
|
||||
}
|
||||
}
|
||||
|
||||
static void f1ap_write_flows_mapped(const f1ap_flows_mapped_to_drb_t *flows_mapped, F1AP_Flows_Mapped_To_DRB_List_t *asn1_flows_mapped, int n)
|
||||
|
||||
@@ -142,7 +142,7 @@ void *F1AP_DU_task(void *arg) {
|
||||
createF1inst(myInstance, msgSetup, nc);
|
||||
du_task_send_sctp_association_req(myInstance, nc);
|
||||
instance_t gtpInst = du_create_gtpu_instance_to_cu(nc);
|
||||
AssertFatal(gtpInst != 0, "cannot create DU F1-U GTP module\n");
|
||||
AssertFatal(gtpInst > 0, "cannot create DU F1-U GTP module\n");
|
||||
getCxt(myInstance)->gtpInst = gtpInst;
|
||||
DUuniqInstance = gtpInst;
|
||||
} break;
|
||||
|
||||
@@ -111,8 +111,9 @@ static void f1ap_read_drb_nssai(const F1AP_SNSSAI_t *asn1_nssai, nssai_t *nssai)
|
||||
{
|
||||
OCTET_STRING_TO_INT8(&asn1_nssai->sST, nssai->sst);
|
||||
nssai->sd = 0xffffff;
|
||||
if (asn1_nssai->sD != NULL)
|
||||
memcpy((uint8_t *)&nssai->sd, asn1_nssai->sD->buf, 3);
|
||||
if (asn1_nssai->sD != NULL) {
|
||||
BUFFER_TO_INT24(asn1_nssai->sD->buf, nssai->sd);
|
||||
}
|
||||
}
|
||||
|
||||
int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
|
||||
@@ -735,7 +735,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
|
||||
return -1;
|
||||
}
|
||||
dlsch_pdu->rb_offset = dlsch_pdu->start_rb + dlsch_pdu->BWPStart;
|
||||
if (mac->get_sib1)
|
||||
if (mac->get_sib1 || mac->get_otherSI)
|
||||
dlsch_pdu->rb_offset -= dlsch_pdu->BWPStart;
|
||||
|
||||
/* TIME_DOM_RESOURCE_ASSIGNMENT */
|
||||
|
||||
@@ -136,7 +136,7 @@ int precoding_weigths_generation(nfapi_nr_pm_list_t *mat,
|
||||
double complex res_code;
|
||||
for (int i_rows = 0; i_rows < N1 * N2; i_rows++) {
|
||||
nfapi_nr_pm_weights_t *weights = &mat->pmi_pdu[pmiq].weights[j_col][i_rows];
|
||||
res_code = sqrt(1 / (double)(L * num_antenna_ports)) * v_lm[llc][mmc][i_rows];
|
||||
res_code = sqrt(1 / (double)L) * v_lm[llc][mmc][i_rows];
|
||||
c16_t precoder_weight = convert_precoder_weight(res_code);
|
||||
weights->precoder_weight_Re = precoder_weight.r;
|
||||
weights->precoder_weight_Im = precoder_weight.i;
|
||||
@@ -153,7 +153,7 @@ int precoding_weigths_generation(nfapi_nr_pm_list_t *mat,
|
||||
}
|
||||
for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) {
|
||||
nfapi_nr_pm_weights_t *weights = &mat->pmi_pdu[pmiq].weights[j_col][i_rows];
|
||||
res_code = sqrt(1 / (double)(L * num_antenna_ports)) * (phase_sign)*theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2];
|
||||
res_code = sqrt(1 / (double)L) * (phase_sign)*theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2];
|
||||
c16_t precoder_weight = convert_precoder_weight(res_code);
|
||||
weights->precoder_weight_Re = precoder_weight.r;
|
||||
weights->precoder_weight_Im = precoder_weight.i;
|
||||
|
||||
@@ -924,6 +924,9 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
|
||||
1, // Not toggling NDI in msg3 retransmissions
|
||||
ul_bwp);
|
||||
|
||||
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
|
||||
ra->msg3_TPC = 1;
|
||||
|
||||
fill_dci_pdu_rel15(sc_info,
|
||||
&ra->DL_BWP,
|
||||
ul_bwp,
|
||||
@@ -2199,6 +2202,9 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
||||
rbStart,
|
||||
rbSize);
|
||||
|
||||
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
|
||||
sched_ctrl->tpc1 = 1;
|
||||
|
||||
// Add padding header and zero rest out if there is space left
|
||||
if (ra->mac_pdu_length < harq->tb_size) {
|
||||
NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[ra->mac_pdu_length];
|
||||
@@ -2351,7 +2357,7 @@ static void nr_fill_rar(uint8_t Mod_idP, NR_RA_t *ra, uint8_t *dlsch_buffer, nfa
|
||||
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 2);
|
||||
unsigned char csi_req = 0, tpc_command;
|
||||
|
||||
tpc_command = 3; // this is 0 dB
|
||||
tpc_command = 3; // This is 0 dB in RAR UL grant
|
||||
|
||||
/// E/T/R/R/BI subheader ///
|
||||
// E = 1, MAC PDU includes another MAC sub-PDU (RAPID)
|
||||
@@ -2383,7 +2389,7 @@ static void nr_fill_rar(uint8_t Mod_idP, NR_RA_t *ra, uint8_t *dlsch_buffer, nfa
|
||||
|
||||
// UL grant
|
||||
|
||||
ra->msg3_TPC = tpc_command;
|
||||
ra->msg3_TPC = 1; // This is 0 dB in UL DCI
|
||||
|
||||
if (pusch_pdu->frequency_hopping)
|
||||
AssertFatal(1==0,"PUSCH with frequency hopping currently not supported");
|
||||
|
||||
@@ -1227,6 +1227,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
dci_payload.ndi = harq->ndi;
|
||||
dci_payload.dai[0].val = pucch ? (pucch->dai_c-1)&3 : 0;
|
||||
dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213
|
||||
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
|
||||
sched_ctrl->tpc1 = 1;
|
||||
dci_payload.pucch_resource_indicator = pucch ? pucch->resource_indicator : 0;
|
||||
dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch ? pucch->timing_indicator : 0; // PDSCH to HARQ TI
|
||||
dci_payload.antenna_ports.val = dmrs_parms->dmrs_ports_id;
|
||||
|
||||
@@ -1119,6 +1119,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
}
|
||||
/* phy-test has hardcoded allocation, so no use to handle CSI reports */
|
||||
if ((uci_234->pduBitmap >> 2) & 0x01 && !get_softmodem_params()->phy_test) {
|
||||
LOG_D(NR_MAC, "CSI CRC %d\n", uci_234->csi_part1.csi_part1_crc);
|
||||
if (uci_234->csi_part1.csi_part1_crc != 1) {
|
||||
// API to parse the csi report and store it into sched_ctrl
|
||||
extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE, nrmac->common_channels->ServingCellConfigCommon);
|
||||
|
||||
@@ -2620,6 +2620,9 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
|
||||
cur_harq->ndi,
|
||||
current_BWP);
|
||||
|
||||
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
|
||||
UE->UE_sched_ctrl.tpc0 = 1;
|
||||
|
||||
fill_dci_pdu_rel15(&UE->sc_info,
|
||||
&UE->current_DL_BWP,
|
||||
current_BWP,
|
||||
|
||||
@@ -767,8 +767,10 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
nr_rlc_pdu_decoder_init(&decoder, buffer, size);
|
||||
dc = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
|
||||
|
||||
if (dc == 0)
|
||||
if (dc == 0) {
|
||||
LOG_D(RLC, "RLC received control PDU\n");
|
||||
return process_control_pdu(entity, buffer, size);
|
||||
}
|
||||
|
||||
/* data PDU */
|
||||
p = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
|
||||
@@ -839,6 +841,7 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
entity->rx_list, pdu);
|
||||
|
||||
/* do reception actions (38.322 5.2.3.2.3) */
|
||||
LOG_D(RLC, "RLC received PDU sn %d so %d is_first %d is_last %d data_size = %d \n", sn, so, is_first, is_last, data_size);
|
||||
reception_actions(entity, pdu);
|
||||
|
||||
if (p) {
|
||||
@@ -852,15 +855,14 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
entity->status_triggered = 1;
|
||||
if (!(sn_compare_rx(entity, sn, entity->rx_highest_status) < 0 ||
|
||||
sn_compare_rx(entity, sn, v) >= 0)) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: STATUS trigger should be delayed, according to specs\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
LOG_D(RLC, "warning: STATUS triggerered but should be delayed according to specs\n");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
LOG_W(RLC, "%s:%d:%s: error decoding PDU, discarding\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
LOG_W(RLC, "RX error decoding PDU, discarding\n");
|
||||
goto discard;
|
||||
|
||||
discard:
|
||||
@@ -978,10 +980,7 @@ static nr_rlc_sdu_segment_t *resegment(nr_rlc_sdu_segment_t *sdu,
|
||||
pdu_header_size = compute_pdu_header_size(entity, sdu);
|
||||
|
||||
next = calloc(1, sizeof(nr_rlc_sdu_segment_t));
|
||||
if (next == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
AssertFatal(next != NULL, "out of memory\n");
|
||||
*next = *sdu;
|
||||
|
||||
over_size = pdu_header_size + sdu->size - pdu_size;
|
||||
@@ -994,7 +993,6 @@ static nr_rlc_sdu_segment_t *resegment(nr_rlc_sdu_segment_t *sdu,
|
||||
next->size = over_size;
|
||||
next->so = sdu->so + sdu->size;
|
||||
next->is_first = 0;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
@@ -1594,6 +1592,8 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer,
|
||||
entity->force_poll = 0;
|
||||
}
|
||||
|
||||
LOG_D(RLC, "RLC TX: sending sdu sn = %d is_first = %d, is_last = %d size = %d\n", sdu->sdu->sn, sdu->is_first, sdu->is_last, size);
|
||||
|
||||
int ret_size = serialize_sdu(entity, sdu, buffer, size, p);
|
||||
entity->common.stats.txpdu_pkts++;
|
||||
entity->common.stats.txpdu_bytes += ret_size;
|
||||
@@ -1612,11 +1612,14 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
|
||||
int p;
|
||||
|
||||
/* sn out of window (that is: we have window stalling)? do nothing */
|
||||
if (is_window_stalling(entity))
|
||||
if (is_window_stalling(entity)) {
|
||||
LOG_D(RLC, "Abort transmit due to window stall\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (entity->tx_list == NULL)
|
||||
if (entity->tx_list == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdu = entity->tx_list;
|
||||
|
||||
@@ -1645,6 +1648,7 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
|
||||
|
||||
/* segment if necessary */
|
||||
if (pdu_size > size) {
|
||||
LOG_D(RLC, "Segmentation (header %d + data %d) / (%d)\n", pdu_header_size, size - pdu_header_size, pdu_size - pdu_header_size);
|
||||
nr_rlc_sdu_segment_t *next_sdu;
|
||||
next_sdu = resegment(sdu, entity, size);
|
||||
/* put the second SDU back at the head of the TX list */
|
||||
@@ -1693,7 +1697,7 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
|
||||
entity->common.stats.txpdu_pkts++;
|
||||
entity->common.stats.txpdu_bytes += ret_size;
|
||||
|
||||
/* No need to 'zero' time-of-arrival;
|
||||
/* No need to 'zero' time-of-arrival;
|
||||
Segmented packets do need to be duplicated in time-sensitive use cases */
|
||||
if (entity->common.avg_time_is_on) {
|
||||
uint64_t time_now = time_average_now();
|
||||
@@ -1701,6 +1705,14 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
|
||||
time_average_add(entity->common.txsdu_avg_time_to_tx, time_now, waited_time);
|
||||
}
|
||||
|
||||
LOG_D(RLC,
|
||||
"RLC TX: sending sdu sn = %d is_first = %d, is_last = %d header size = %d data size = %d\n",
|
||||
sdu->sdu->sn,
|
||||
sdu->is_first,
|
||||
sdu->is_last,
|
||||
pdu_header_size,
|
||||
size - pdu_header_size);
|
||||
|
||||
return ret_size;
|
||||
// return serialize_sdu(entity, sdu, buffer, size, p);
|
||||
}
|
||||
@@ -1730,14 +1742,18 @@ int nr_rlc_entity_am_generate_pdu(nr_rlc_entity_t *_entity,
|
||||
|
||||
if (status_to_report(entity)) {
|
||||
ret = generate_status(entity, buffer, size);
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
LOG_D(RLC, "RLC transmit status pdu PDU\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity->retransmit_list != NULL) {
|
||||
ret = generate_retx_pdu(entity, buffer, size);
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
LOG_D(RLC, "RLC retransmit PDU\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return generate_tx_pdu(entity, buffer, size);
|
||||
@@ -1756,11 +1772,7 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
|
||||
|
||||
entity->common.stats.rxsdu_pkts++;
|
||||
|
||||
if (size > NR_SDU_MAX) {
|
||||
LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, size);
|
||||
exit(1);
|
||||
}
|
||||
AssertFatal(size <= NR_SDU_MAX, "Fatal: SDU size too big (%d bytes)\n", size);
|
||||
|
||||
/* log SDUs rejected, at most once per second */
|
||||
if (entity->sdu_rejected != 0
|
||||
|
||||
@@ -12,3 +12,13 @@ add_test(NAME nr_rlc_tests
|
||||
COMMAND exec_nr_rlc_test.sh ${CMAKE_CURRENT_BINARY_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_executable(test_nr_rlc_am_entity test_nr_rlc_am_entity.cpp)
|
||||
target_link_libraries(test_nr_rlc_am_entity PRIVATE nr_rlc_core GTest::gtest minimal_lib)
|
||||
add_dependencies(tests test_nr_rlc_am_entity)
|
||||
add_test(NAME test_nr_rlc_am_entity COMMAND ./test_nr_rlc_am_entity)
|
||||
|
||||
add_executable(benchmark_nr_rlc_am_entity benchmark_nr_rlc_am_entity.cpp)
|
||||
target_link_libraries(benchmark_nr_rlc_am_entity PRIVATE benchmark::benchmark nr_rlc_core UTIL ${T_LIB} minimal_lib)
|
||||
add_dependencies(tests benchmark_nr_rlc_am_entity)
|
||||
add_test(NAME benchmark_nr_rlc_am_entity
|
||||
COMMAND ./benchmark_nr_rlc_am_entity)
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#include "benchmark/benchmark.h"
|
||||
extern "C" {
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/config/config_load_configmodule.h"
|
||||
extern configmodule_interface_t *uniqCfg;
|
||||
}
|
||||
#include <iostream>
|
||||
|
||||
void deliver_sdu(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size)
|
||||
{
|
||||
}
|
||||
void sdu_successful_delivery(void *sdu_successful_delivery_data, struct nr_rlc_entity_t *entity, int sdu_id)
|
||||
{
|
||||
}
|
||||
void max_retx_reached(void *max_retx_reached_data, struct nr_rlc_entity_t *entity)
|
||||
{
|
||||
}
|
||||
|
||||
static void BM_nr_rlc_am_entity(benchmark::State &state)
|
||||
{
|
||||
nr_rlc_entity_t *tx_entity = new_nr_rlc_entity_am(10000,
|
||||
10000,
|
||||
deliver_sdu,
|
||||
NULL,
|
||||
sdu_successful_delivery,
|
||||
NULL,
|
||||
max_retx_reached,
|
||||
NULL,
|
||||
5,
|
||||
35,
|
||||
0,
|
||||
4,
|
||||
-1,
|
||||
8,
|
||||
12);
|
||||
|
||||
nr_rlc_entity_t *rx_entity = new_nr_rlc_entity_am(10000,
|
||||
10000,
|
||||
deliver_sdu,
|
||||
NULL,
|
||||
sdu_successful_delivery,
|
||||
NULL,
|
||||
max_retx_reached,
|
||||
NULL,
|
||||
5,
|
||||
35,
|
||||
0,
|
||||
4,
|
||||
-1,
|
||||
8,
|
||||
12);
|
||||
|
||||
char message[] = "Message to the other RLC AM entity.";
|
||||
for (auto _ : state) {
|
||||
char pdu_buf[40];
|
||||
for (int i = 0; i < state.range(0); i++) {
|
||||
tx_entity->recv_sdu(tx_entity, message, sizeof(message), i);
|
||||
int size = tx_entity->generate_pdu(tx_entity, pdu_buf, sizeof(pdu_buf));
|
||||
if (size != 0) {
|
||||
// 10% packet loss
|
||||
if (i % 10 != 0)
|
||||
rx_entity->recv_pdu(rx_entity, pdu_buf, size);
|
||||
}
|
||||
// Allow the lists to build up before sending messages in the other direction
|
||||
if (i % 100 == 0) {
|
||||
size = rx_entity->generate_pdu(rx_entity, pdu_buf, sizeof(pdu_buf));
|
||||
if (size != 0) {
|
||||
// No packet lost in the other direction
|
||||
tx_entity->recv_pdu(tx_entity, pdu_buf, size);
|
||||
}
|
||||
}
|
||||
tx_entity->set_time(tx_entity, i + 1);
|
||||
rx_entity->set_time(tx_entity, i + 1);
|
||||
}
|
||||
}
|
||||
tx_entity->delete_entity(tx_entity);
|
||||
rx_entity->delete_entity(rx_entity);
|
||||
}
|
||||
|
||||
BENCHMARK(BM_nr_rlc_am_entity)->RangeMultiplier(4)->Range(100, 20000);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logInit();
|
||||
uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY);
|
||||
g_log->log_component[RLC].level = -1;
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
extern "C" {
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/config/config_load_configmodule.h"
|
||||
extern configmodule_interface_t *uniqCfg;
|
||||
}
|
||||
#include <iostream>
|
||||
|
||||
int sdu_delivered_count = 0;
|
||||
int sdu_acked_count = 0;
|
||||
void deliver_sdu(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size)
|
||||
{
|
||||
sdu_delivered_count++;
|
||||
char payload[300];
|
||||
ASSERT_LE(size, sizeof(payload));
|
||||
snprintf(payload, size, "%s", buf);
|
||||
std::cout << "Delivered sdu: " << payload << std::endl;
|
||||
}
|
||||
|
||||
void sdu_successful_delivery(void *sdu_successful_delivery_data, struct nr_rlc_entity_t *entity, int sdu_id)
|
||||
{
|
||||
sdu_acked_count++;
|
||||
std::cout << "SDU " << sdu_id << " acked" << std::endl;
|
||||
}
|
||||
|
||||
void max_retx_reached(void *max_retx_reached_data, struct nr_rlc_entity_t *entity)
|
||||
{
|
||||
}
|
||||
|
||||
TEST(nr_rlc_am_entity, test_init)
|
||||
{
|
||||
nr_rlc_entity_t *entity = new_nr_rlc_entity_am(100,
|
||||
100,
|
||||
deliver_sdu,
|
||||
NULL,
|
||||
sdu_successful_delivery,
|
||||
NULL,
|
||||
max_retx_reached,
|
||||
NULL,
|
||||
45,
|
||||
35,
|
||||
0,
|
||||
-1,
|
||||
-1,
|
||||
8,
|
||||
12);
|
||||
char buf[30];
|
||||
EXPECT_EQ(entity->generate_pdu(entity, buf, sizeof(buf)), 0) << "No PDCP SDU provided to RLC, expected no RLC PDUS";
|
||||
|
||||
entity->delete_entity(entity);
|
||||
}
|
||||
|
||||
TEST(nr_rlc_am_entity, test_segmentation_reassembly)
|
||||
{
|
||||
nr_rlc_entity_t *tx_entity = new_nr_rlc_entity_am(100,
|
||||
100,
|
||||
deliver_sdu,
|
||||
NULL,
|
||||
sdu_successful_delivery,
|
||||
NULL,
|
||||
max_retx_reached,
|
||||
NULL,
|
||||
45,
|
||||
35,
|
||||
0,
|
||||
-1,
|
||||
-1,
|
||||
8,
|
||||
12);
|
||||
|
||||
nr_rlc_entity_t *rx_entity = new_nr_rlc_entity_am(100,
|
||||
100,
|
||||
deliver_sdu,
|
||||
NULL,
|
||||
sdu_successful_delivery,
|
||||
NULL,
|
||||
max_retx_reached,
|
||||
NULL,
|
||||
45,
|
||||
35,
|
||||
0,
|
||||
-1,
|
||||
-1,
|
||||
8,
|
||||
12);
|
||||
char buf[30] = {0};
|
||||
snprintf(buf, sizeof(buf), "%s", "Message");
|
||||
EXPECT_EQ(tx_entity->generate_pdu(tx_entity, buf, sizeof(buf)), 0) << "No PDCP SDU provided to RLC, expected no RLC PDUS";
|
||||
|
||||
// Higher layer IF -> deliver PDCP SDU
|
||||
tx_entity->recv_sdu(tx_entity, buf, sizeof(buf), 0);
|
||||
sdu_delivered_count = 0;
|
||||
for (auto i = 0; i < 10; i++) {
|
||||
if (sdu_delivered_count == 1) {
|
||||
break;
|
||||
}
|
||||
int size = tx_entity->generate_pdu(tx_entity, buf, 10);
|
||||
EXPECT_GT(size, 0);
|
||||
rx_entity->recv_pdu(rx_entity, buf, size);
|
||||
}
|
||||
EXPECT_EQ(sdu_delivered_count, 1);
|
||||
sdu_acked_count = 0;
|
||||
int size = rx_entity->generate_pdu(rx_entity, buf, 30);
|
||||
tx_entity->recv_pdu(tx_entity, buf, size);
|
||||
EXPECT_EQ(sdu_acked_count, 1);
|
||||
|
||||
tx_entity->delete_entity(tx_entity);
|
||||
rx_entity->delete_entity(rx_entity);
|
||||
}
|
||||
|
||||
TEST(nr_rlc_am_entity, test_ack_out_of_order)
|
||||
{
|
||||
nr_rlc_entity_t *tx_entity = new_nr_rlc_entity_am(100,
|
||||
100,
|
||||
deliver_sdu,
|
||||
NULL,
|
||||
sdu_successful_delivery,
|
||||
NULL,
|
||||
max_retx_reached,
|
||||
NULL,
|
||||
5,
|
||||
35,
|
||||
0,
|
||||
4,
|
||||
-1,
|
||||
8,
|
||||
12);
|
||||
|
||||
nr_rlc_entity_t *rx_entity = new_nr_rlc_entity_am(100,
|
||||
100,
|
||||
deliver_sdu,
|
||||
NULL,
|
||||
sdu_successful_delivery,
|
||||
NULL,
|
||||
max_retx_reached,
|
||||
NULL,
|
||||
5,
|
||||
35,
|
||||
0,
|
||||
4,
|
||||
-1,
|
||||
8,
|
||||
12);
|
||||
|
||||
char buf[30] = {0};
|
||||
EXPECT_EQ(tx_entity->generate_pdu(tx_entity, buf, sizeof(buf)), 0) << "No PDCP SDU provided to RLC, expected no RLC PDUS";
|
||||
// Higher layer IF -> deliver PDCP SDU
|
||||
// Generate 4 PDCP SDUS
|
||||
snprintf(buf, sizeof(buf), "%s", "Message 1");
|
||||
tx_entity->recv_sdu(tx_entity, buf, sizeof(buf), 0);
|
||||
snprintf(buf, sizeof(buf), "%s", "Message 2");
|
||||
tx_entity->recv_sdu(tx_entity, buf, sizeof(buf), 1);
|
||||
snprintf(buf, sizeof(buf), "%s", "Message 3");
|
||||
tx_entity->recv_sdu(tx_entity, buf, sizeof(buf), 2);
|
||||
|
||||
sdu_delivered_count = 0;
|
||||
sdu_acked_count = 0;
|
||||
char pdu_buf[40];
|
||||
uint64_t time = 0;
|
||||
for (auto i = 0; i < 3; i++) {
|
||||
int size = tx_entity->generate_pdu(tx_entity, pdu_buf, sizeof(pdu_buf));
|
||||
EXPECT_GT(size, 0);
|
||||
// Do not deliver PDU 2 to RX entity
|
||||
if (i != 1) {
|
||||
rx_entity->recv_pdu(rx_entity, pdu_buf, size);
|
||||
}
|
||||
tx_entity->set_time(tx_entity, time);
|
||||
rx_entity->set_time(tx_entity, time);
|
||||
time++;
|
||||
}
|
||||
EXPECT_EQ(sdu_delivered_count, 2) << "Expected 2 out of 3 SDUs delivered";
|
||||
|
||||
int size = rx_entity->generate_pdu(rx_entity, pdu_buf, sizeof(pdu_buf));
|
||||
EXPECT_GT(size, 0);
|
||||
tx_entity->recv_pdu(tx_entity, pdu_buf, size);
|
||||
|
||||
// Triggers t-poll-retransmit and retransmission of the lost PDU
|
||||
for (auto i = 0; i < 5; i++) {
|
||||
tx_entity->set_time(tx_entity, time);
|
||||
rx_entity->set_time(tx_entity, time);
|
||||
size = tx_entity->generate_pdu(tx_entity, pdu_buf, sizeof(pdu_buf));
|
||||
if (size != 0)
|
||||
rx_entity->recv_pdu(rx_entity, pdu_buf, size);
|
||||
size = rx_entity->generate_pdu(rx_entity, pdu_buf, sizeof(pdu_buf));
|
||||
if (size != 0)
|
||||
tx_entity->recv_pdu(tx_entity, pdu_buf, size);
|
||||
time++;
|
||||
}
|
||||
EXPECT_EQ(sdu_acked_count, 3);
|
||||
EXPECT_EQ(sdu_delivered_count, 3);
|
||||
|
||||
tx_entity->delete_entity(tx_entity);
|
||||
rx_entity->delete_entity(rx_entity);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logInit();
|
||||
uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY);
|
||||
g_log->log_component[RLC].level = OAILOG_TRACE;
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -44,13 +44,6 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
uint8_t *inde_list
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
);
|
||||
|
||||
/*! \fn rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(module_id_t enb_mod_idP, const rrc_eNB_ue_context_t* const ue_context_pP)
|
||||
*\brief Send GTPV1U_ENB_DELETE_TUNNEL_REQ message to GTPV1U to destroy all UE-related tunnels.
|
||||
*\param module_id Instance ID of eNB.
|
||||
|
||||
@@ -519,12 +519,10 @@ int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
return ((enc_rval.encoded + 7) / 8);
|
||||
}
|
||||
|
||||
int do_NR_SecurityModeCommand(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id,
|
||||
const uint8_t cipheringAlgorithm,
|
||||
NR_IntegrityProtAlgorithm_t integrityProtAlgorithm)
|
||||
int do_NR_SecurityModeCommand(uint8_t *const buffer,
|
||||
const uint8_t Transaction_id,
|
||||
const uint8_t cipheringAlgorithm,
|
||||
NR_IntegrityProtAlgorithm_t integrityProtAlgorithm)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg={0};
|
||||
@@ -555,19 +553,13 @@ int do_NR_SecurityModeCommand(
|
||||
AssertFatal(enc_rval.encoded >0 , "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message,&dl_dcch_msg);
|
||||
LOG_D(NR_RRC, "[gNB %d] securityModeCommand for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8);
|
||||
|
||||
// rrc_ue_process_ueCapabilityEnquiry(0,1000,&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry,0);
|
||||
// exit(-1);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
/*TODO*/
|
||||
//------------------------------------------------------------------------------
|
||||
int do_NR_SA_UECapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id)
|
||||
//------------------------------------------------------------------------------
|
||||
int do_NR_SA_UECapabilityEnquiry(uint8_t *const buffer, const uint8_t Transaction_id)
|
||||
{
|
||||
NR_UE_CapabilityRequestFilterNR_t *sa_band_filter;
|
||||
NR_FreqBandList_t *sa_band_list;
|
||||
@@ -627,7 +619,7 @@ int do_NR_SA_UECapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP,
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message, &dl_dcch_msg);
|
||||
|
||||
LOG_D(NR_RRC, "[gNB %d] NR UECapabilityRequest for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8);
|
||||
LOG_D(NR_RRC, "NR UECapabilityRequestEncoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded + 7) / 8);
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
@@ -81,16 +81,12 @@ int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const gNB_RrcConfigurationReq *configuration,
|
||||
NR_SRB_ToAddModList_t *SRBs);
|
||||
|
||||
int do_NR_SecurityModeCommand(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id,
|
||||
const uint8_t cipheringAlgorithm,
|
||||
NR_IntegrityProtAlgorithm_t integrityProtAlgorithm);
|
||||
int do_NR_SecurityModeCommand(uint8_t *const buffer,
|
||||
const uint8_t Transaction_id,
|
||||
const uint8_t cipheringAlgorithm,
|
||||
NR_IntegrityProtAlgorithm_t integrityProtAlgorithm);
|
||||
|
||||
int do_NR_SA_UECapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id);
|
||||
int do_NR_SA_UECapabilityEnquiry(uint8_t *const buffer, const uint8_t Transaction_id);
|
||||
|
||||
int do_NR_RRCRelease(uint8_t *buffer, size_t buffer_size, uint8_t Transaction_id);
|
||||
|
||||
|
||||
@@ -37,9 +37,8 @@ TEST(nr_asn1, rrc_reject)
|
||||
|
||||
TEST(nr_asn1, sa_capability_enquiry)
|
||||
{
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
unsigned char buf[1000];
|
||||
EXPECT_GT(do_NR_SA_UECapabilityEnquiry(&ctxt, buf, 0), 0);
|
||||
EXPECT_GT(do_NR_SA_UECapabilityEnquiry(buf, 0), 0);
|
||||
}
|
||||
|
||||
TEST(nr_asn1, rrc_reconfiguration_complete_for_nsa)
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file nr_rrc_common.c
|
||||
* \brief rrc common procedures for gNB
|
||||
* \author Navid Nikaein and Raymond Knopp, WEI-TAI CHEN
|
||||
* \date 2011 - 2014, 2018
|
||||
* \version 1.0
|
||||
* \company Eurecom, NTUST
|
||||
* \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr, kroempa@gmail.com
|
||||
*/
|
||||
|
||||
#include "nr_rrc_extern.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "COMMON/openair_defs.h"
|
||||
#include "common/platform_types.h"
|
||||
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
||||
#include "LAYER2/RLC/rlc.h"
|
||||
#include "COMMON/mac_rrc_primitives.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "asn1_msg.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/ran_context.h"
|
||||
|
||||
#define DEBUG_NR_RRC 1
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern UE_MAC_INST *UE_mac_inst;
|
||||
extern mui_t rrc_gNB_mui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan)
|
||||
{
|
||||
chan->transport_block_size = 4;
|
||||
chan->max_transport_blocks = 16;
|
||||
chan->Delay_class = 1;
|
||||
return;
|
||||
}
|
||||
@@ -59,6 +59,4 @@ typedef struct SRB_INFO_TABLE_ENTRY_NR_s {
|
||||
uint8_t status;
|
||||
} NR_SRB_INFO_TABLE_ENTRY;
|
||||
|
||||
void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,19 +45,6 @@
|
||||
#include "NR_CellGroupConfig.h"
|
||||
|
||||
#define NR_MAX_SUPPORTED_DL_LAYERS 4
|
||||
void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan);
|
||||
|
||||
void rrc_gNB_process_SgNBAdditionRequest(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP
|
||||
);
|
||||
|
||||
void rrc_gNB_generate_SgNBAdditionRequestAcknowledge(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
);
|
||||
|
||||
rrc_gNB_ue_context_t *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP);
|
||||
|
||||
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t * cg_config_info);
|
||||
|
||||
@@ -72,21 +59,13 @@ NR_CG_Config_t *generate_CG_Config(const NR_RRCReconfiguration_t *reconfig, cons
|
||||
|
||||
int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m);
|
||||
|
||||
void rrc_gNB_generate_SecurityModeCommand(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP);
|
||||
void rrc_gNB_generate_SecurityModeCommand(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p);
|
||||
|
||||
void rrc_forward_ue_nas_message(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE);
|
||||
|
||||
unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP);
|
||||
|
||||
void
|
||||
rrc_gNB_generate_UECapabilityEnquiry(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
);
|
||||
|
||||
void
|
||||
rrc_gNB_generate_RRCRelease(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
);
|
||||
void rrc_gNB_generate_RRCRelease(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE);
|
||||
|
||||
/**\brief RRC eNB task.
|
||||
\param args_p Pointer on arguments to start the task. */
|
||||
@@ -100,20 +79,13 @@ void *rrc_gnb_task(void *args_p);
|
||||
\ *reOffset Pointer to RE Offset Value */
|
||||
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, long *ptrsNrb, long *ptrsMcs, long *epre_Ratio, long *reOffset);
|
||||
|
||||
int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
protocol_ctxt_t *const ctxt_pP,
|
||||
const int dl_bwp_id,
|
||||
const int ul_bwp_id);
|
||||
int nr_rrc_reconfiguration_req(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p, const int dl_bwp_id, const int ul_bwp_id);
|
||||
|
||||
void
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid,
|
||||
uint32_t nas_length,
|
||||
uint8_t *nas_buffer);
|
||||
|
||||
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP);
|
||||
void rrc_gNB_generate_dedicatedRRCReconfiguration_release(gNB_RRC_INST *rrc,
|
||||
gNB_RRC_UE_t *ue_p,
|
||||
uint8_t xid,
|
||||
uint32_t nas_length,
|
||||
uint8_t *nas_buffer);
|
||||
|
||||
bool ue_associated_to_cuup(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue);
|
||||
sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue);
|
||||
|
||||
+129
-317
@@ -471,25 +471,19 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context
|
||||
/*
|
||||
* Process the rrc setup complete message from UE (SRB1 Active)
|
||||
*/
|
||||
static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, NR_RRCSetupComplete_IEs_t *rrcSetupComplete)
|
||||
static void rrc_gNB_process_RRCSetupComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRCSetupComplete_IEs_t *rrcSetupComplete)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
LOG_A(NR_RRC, "UE %d Processing NR_RRCSetupComplete from UE\n", ue_context_pP->ue_context.rrc_ue_id);
|
||||
ue_context_pP->ue_context.Srb[1].Active = 1;
|
||||
ue_context_pP->ue_context.Srb[2].Active = 0;
|
||||
AssertFatal(ctxt_pP->rntiMaybeUEid == ue_context_pP->ue_context.rrc_ue_id, "logic bug: inconsistent IDs, must use CU UE ID!\n");
|
||||
LOG_A(NR_RRC, "UE %d Processing NR_RRCSetupComplete from UE\n", UE->rrc_ue_id);
|
||||
UE->Srb[1].Active = 1;
|
||||
UE->Srb[2].Active = 0;
|
||||
|
||||
rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete);
|
||||
rrc_gNB_send_NGAP_NAS_FIRST_REQ(rrc, UE, rrcSetupComplete);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
static void rrc_gNB_generate_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
||||
{
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
ue_p->xids[xid] = RRC_PDUSESSION_ESTABLISH;
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList));
|
||||
|
||||
@@ -570,29 +564,13 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
|
||||
ue_p->DRB_ReleaseList = NULL;
|
||||
|
||||
LOG_I(NR_RRC, "UE %d: Generate RRCReconfiguration (bytes %d, xid %d)\n", ue_p->rrc_ue_id, size, xid);
|
||||
LOG_D(NR_RRC,
|
||||
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
|
||||
ctxt_pP->frame,
|
||||
ctxt_pP->module_id,
|
||||
size,
|
||||
ue_p->rnti,
|
||||
rrc_gNB_mui,
|
||||
ctxt_pP->module_id,
|
||||
DCCH);
|
||||
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_modify_dedicatedRRCReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
int qos_flow_index = 0;
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
ue_p->xids[xid] = RRC_PDUSESSION_MODIFY;
|
||||
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList =
|
||||
@@ -694,33 +672,18 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
|
||||
for (int i = 0; i < ue_p->nb_of_pdusessions; i++)
|
||||
clear_nas_pdu(&ue_p->pduSession[i].param.nas_pdu);
|
||||
|
||||
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti);
|
||||
LOG_D(NR_RRC,
|
||||
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
|
||||
ctxt_pP->frame,
|
||||
ctxt_pP->module_id,
|
||||
size,
|
||||
ue_p->rnti,
|
||||
rrc_gNB_mui,
|
||||
ctxt_pP->module_id,
|
||||
DCCH);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
LOG_I(NR_RRC, "UE %d: Generate RRCReconfiguration (bytes %d)\n", ue_p->rrc_ue_id, size);
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid,
|
||||
uint32_t nas_length,
|
||||
uint8_t *nas_buffer)
|
||||
void rrc_gNB_generate_dedicatedRRCReconfiguration_release(gNB_RRC_INST *rrc,
|
||||
gNB_RRC_UE_t *ue_p,
|
||||
uint8_t xid,
|
||||
uint32_t nas_length,
|
||||
uint8_t *nas_buffer)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
|
||||
NR_DRB_ToReleaseList_t *DRB_Release_configList2 = CALLOC(sizeof(*DRB_Release_configList2), 1);
|
||||
|
||||
for (int i = 0; i < NB_RB_MAX; i++) {
|
||||
@@ -761,18 +724,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
||||
free(nas_buffer);
|
||||
}
|
||||
|
||||
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti);
|
||||
LOG_D(NR_RRC,
|
||||
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
|
||||
ctxt_pP->frame,
|
||||
ctxt_pP->module_id,
|
||||
size,
|
||||
ue_p->rnti,
|
||||
rrc_gNB_mui,
|
||||
ctxt_pP->module_id,
|
||||
DCCH);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
LOG_I(NR_RRC, "UE %d: Generate NR_RRCReconfiguration (bytes %d)\n", ue_p->rrc_ue_id, size);
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
|
||||
}
|
||||
|
||||
@@ -919,15 +871,8 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
|
||||
}
|
||||
|
||||
/// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request.
|
||||
/// @param ctxt_pP Protocol context containing information regarding the UE and gNB
|
||||
/// @param reestablish_rnti is the old C-RNTI
|
||||
/// @param ue_context_pP UE context container information regarding the UE
|
||||
/// @param xid Transaction Identifier used in RRC messages
|
||||
static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
const uint8_t xid)
|
||||
static void rrc_gNB_process_RRCReestablishmentComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p, const uint8_t xid)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
LOG_I(NR_RRC, "UE %d Processing NR_RRCReestablishmentComplete from UE\n", ue_p->rrc_ue_id);
|
||||
|
||||
int i = 0;
|
||||
@@ -936,7 +881,6 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
|
||||
|
||||
ue_p->Srb[1].Active = 1;
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
||||
|
||||
cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig;
|
||||
@@ -982,7 +926,7 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
|
||||
/* Create drb-ToAddModList */
|
||||
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, true);
|
||||
|
||||
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
ue_p->xids[new_xid] = RRC_REESTABLISH_COMPLETE;
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
|
||||
int size = do_RRCReconfiguration(ue_p,
|
||||
@@ -1010,13 +954,9 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
protocol_ctxt_t *const ctxt_pP,
|
||||
const int dl_bwp_id,
|
||||
const int ul_bwp_id)
|
||||
int nr_rrc_reconfiguration_req(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p, const int dl_bwp_id, const int ul_bwp_id)
|
||||
{
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
ue_p->xids[xid] = RRC_DEDICATED_RECONF;
|
||||
|
||||
NR_CellGroupConfig_t *masterCellGroup = ue_p->masterCellGroup;
|
||||
@@ -1031,7 +971,6 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE];
|
||||
int size = do_RRCReconfiguration(ue_p, buffer, NR_RRC_BUF_SIZE, xid, NULL, NULL, NULL, NULL, NULL, NULL, masterCellGroup);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
|
||||
|
||||
return 0;
|
||||
@@ -1207,10 +1146,8 @@ fallback_rrc_setup:
|
||||
return;
|
||||
}
|
||||
|
||||
static void process_Periodical_Measurement_Report(rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport)
|
||||
static void process_Periodical_Measurement_Report(gNB_RRC_UE_t *ue_ctxt, NR_MeasurementReport_t *measurementReport)
|
||||
{
|
||||
// LOG_I(NR_RRC, "Periodical Event Report! Do Nothing for now...\n");
|
||||
gNB_RRC_UE_t *ue_ctxt = &ue_context->ue_context;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_MeasResults, ue_ctxt->measResults);
|
||||
ue_ctxt->measResults = NULL;
|
||||
|
||||
@@ -1300,19 +1237,21 @@ static void process_Event_Based_Measurement_Report(NR_ReportConfigNR_t *report,
|
||||
}
|
||||
}
|
||||
|
||||
static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport)
|
||||
static void rrc_gNB_process_MeasurementReport(gNB_RRC_UE_t *UE, NR_MeasurementReport_t *measurementReport)
|
||||
{
|
||||
LOG_D(NR_RRC, "Process Measurement Report\n");
|
||||
NR_MeasurementReport__criticalExtensions_PR p = measurementReport->criticalExtensions.present;
|
||||
if (p != NR_MeasurementReport__criticalExtensions_PR_measurementReport
|
||||
|| measurementReport->criticalExtensions.choice.measurementReport == NULL) {
|
||||
LOG_E(NR_RRC, "UE %d: expected presence of MeasurementReport, but has %d (%p)\n", UE->rrc_ue_id, p, measurementReport->criticalExtensions.choice.measurementReport);
|
||||
return;
|
||||
}
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_MeasurementReport, (void *)measurementReport);
|
||||
|
||||
DevAssert(measurementReport->criticalExtensions.present == NR_MeasurementReport__criticalExtensions_PR_measurementReport
|
||||
&& measurementReport->criticalExtensions.choice.measurementReport != NULL);
|
||||
|
||||
gNB_RRC_UE_t *ue_ctxt = &ue_context->ue_context;
|
||||
NR_MeasConfig_t *meas_config = ue_ctxt->measConfig;
|
||||
NR_MeasConfig_t *meas_config = UE->measConfig;
|
||||
if (meas_config == NULL) {
|
||||
LOG_I(NR_RRC, "Unexpected Measurement Report from UE with id: %d\n", ue_ctxt->rrc_ue_id);
|
||||
LOG_I(NR_RRC, "Unexpected Measurement Report from UE with id: %d\n", UE->rrc_ue_id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1347,7 +1286,7 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context,
|
||||
}
|
||||
|
||||
if (report_config->choice.reportConfigNR->reportType.present == NR_ReportConfigNR__reportType_PR_periodical)
|
||||
return process_Periodical_Measurement_Report(ue_context, measurementReport);
|
||||
return process_Periodical_Measurement_Report(UE, measurementReport);
|
||||
|
||||
if (report_config->choice.reportConfigNR->reportType.present != NR_ReportConfigNR__reportType_PR_eventTriggered) {
|
||||
LOG_D(NR_RRC, "Incoming Report Type: %d is not supported! \n", report_config->choice.reportConfigNR->reportType.present);
|
||||
@@ -1357,28 +1296,26 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context,
|
||||
process_Event_Based_Measurement_Report(report_config->choice.reportConfigNR, measurementReport);
|
||||
}
|
||||
|
||||
static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_p,
|
||||
const NR_RRCReestablishmentComplete_t *reestablishment_complete)
|
||||
static int handle_rrcReestablishmentComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_RRCReestablishmentComplete_t *cplt)
|
||||
{
|
||||
DevAssert(ue_context_p != NULL);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
|
||||
DevAssert(reestablishment_complete->criticalExtensions.present
|
||||
== NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete);
|
||||
rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, ue_context_p, reestablishment_complete->rrc_TransactionIdentifier);
|
||||
NR_RRCReestablishmentComplete__criticalExtensions_PR p = cplt->criticalExtensions.present;
|
||||
if (p != NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete) {
|
||||
LOG_E(NR_RRC, "UE %d: expected presence of rrcReestablishmentComplete, but message has %d\n", UE->rrc_ue_id, p);
|
||||
return -1;
|
||||
}
|
||||
rrc_gNB_process_RRCReestablishmentComplete(rrc, UE, cplt->rrc_TransactionIdentifier);
|
||||
|
||||
UE->ue_reestablishment_counter++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rrc_forward_ue_nas_message(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
|
||||
void rrc_forward_ue_nas_message(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
|
||||
{
|
||||
if (UE->nas_pdu.buffer == NULL || UE->nas_pdu.length == 0)
|
||||
return; // no problem: the UE will re-request a NAS PDU
|
||||
|
||||
uint8_t buffer[4096];
|
||||
unsigned int xid = rrc_gNB_get_next_transaction_identifier(0);
|
||||
unsigned int xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
uint32_t length = do_NR_DLInformationTransfer(buffer, sizeof(buffer), xid, UE->nas_pdu.length, UE->nas_pdu.buffer);
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, buffer, length, "[MSG] RRC DL Information Transfer\n");
|
||||
rb_id_t srb_id = UE->Srb[2].Active ? DCCH1 : DCCH;
|
||||
@@ -1388,16 +1325,15 @@ static void rrc_forward_ue_nas_message(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
|
||||
UE->nas_pdu.length = 0;
|
||||
}
|
||||
|
||||
static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_p,
|
||||
const NR_UECapabilityInformation_t *ue_cap_info)
|
||||
static void handle_ueCapabilityInformation(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UECapabilityInformation_t *ue_cap_info)
|
||||
{
|
||||
AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
|
||||
int xid = ue_cap_info->rrc_TransactionIdentifier;
|
||||
DevAssert(UE->xids[xid] == RRC_UECAPABILITY_ENQUIRY);
|
||||
rrc_action_t a = UE->xids[xid];
|
||||
UE->xids[xid] = RRC_ACTION_NONE;
|
||||
if (a != RRC_UECAPABILITY_ENQUIRY) {
|
||||
LOG_E(NR_RRC, "UE %d: received unsolicited UE Capability Information, aborting procedure\n", UE->rrc_ue_id);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_I(NR_RRC, "UE %d: received UE capabilities (xid %d)\n", UE->rrc_ue_id, xid);
|
||||
int eutra_index = -1;
|
||||
@@ -1414,7 +1350,7 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
|
||||
(void **)&UE->ue_cap_buffer.buf);
|
||||
if (UE->ue_cap_buffer.len <= 0) {
|
||||
LOG_E(RRC, "could not encode UE-CapabilityRAT-ContainerList, abort handling capabilities\n");
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ue_CapabilityRAT_ContainerList->list.count; i++) {
|
||||
@@ -1437,10 +1373,7 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
|
||||
}
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
LOG_E(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT " Failed to decode nr UE capabilities (%zu bytes)\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
dec_rval.consumed);
|
||||
LOG_E(NR_RRC, "UE %d: Failed to decode nr UE capabilities (%zu bytes)\n", UE->rrc_ue_id, dec_rval.consumed);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
|
||||
UE->UE_Capability_nr = 0;
|
||||
}
|
||||
@@ -1448,7 +1381,7 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
|
||||
UE->UE_Capability_size = ue_cap_container->ue_CapabilityRAT_Container.size;
|
||||
if (eutra_index != -1) {
|
||||
LOG_E(NR_RRC, "fatal: more than 1 eutra capability\n");
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
eutra_index = i;
|
||||
}
|
||||
@@ -1471,10 +1404,7 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
|
||||
}
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
LOG_E(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_FMT " Failed to decode nr UE capabilities (%zu bytes)\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
dec_rval.consumed);
|
||||
LOG_E(NR_RRC, "UE %d: Failed to decode nr UE capabilities (%zu bytes)\n", UE->rrc_ue_id, dec_rval.consumed);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
|
||||
UE->UE_Capability_MRDC = 0;
|
||||
}
|
||||
@@ -1487,41 +1417,33 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
|
||||
}
|
||||
|
||||
if (eutra_index == -1)
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
|
||||
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP, ue_context_p, ue_cap_info);
|
||||
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(rrc, UE, ue_cap_info);
|
||||
|
||||
if (UE->n_initial_pdu > 0) {
|
||||
/* there were PDU sessions with the NG UE Context setup, but we had to set
|
||||
* up security and request capabilities, so trigger PDU sessions now. The
|
||||
* UE NAS message will be forwarded in the corresponding reconfiguration,
|
||||
* the Initial context setup response after reconfiguration complete. */
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0);
|
||||
} else {
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
|
||||
rrc_forward_ue_nas_message(RC.nrrrc[ctxt_pP->instance], UE);
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE);
|
||||
rrc_forward_ue_nas_message(rrc, UE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_p,
|
||||
const NR_RRCSetupComplete_t *setup_complete)
|
||||
static void handle_rrcSetupComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_RRCSetupComplete_t *setup_complete)
|
||||
{
|
||||
if (!ue_context_p) {
|
||||
LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
|
||||
return -1;
|
||||
}
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
uint8_t xid = setup_complete->rrc_TransactionIdentifier;
|
||||
UE->xids[xid] = RRC_ACTION_NONE;
|
||||
|
||||
if (setup_complete->criticalExtensions.present != NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete) {
|
||||
LOG_E(NR_RRC, "malformed RRCSetupComplete received from UE %lx\n", ctxt_pP->rntiMaybeUEid);
|
||||
return -1;
|
||||
LOG_E(NR_RRC, "malformed RRCSetupComplete received from UE %d\n", UE->rrc_ue_id);
|
||||
return;
|
||||
}
|
||||
|
||||
NR_RRCSetupComplete_IEs_t *setup_complete_ies = setup_complete->criticalExtensions.choice.rrcSetupComplete;
|
||||
@@ -1532,7 +1454,7 @@ static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP,
|
||||
const BIT_STRING_t *part2 = &setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2;
|
||||
if (part2->size != 2) {
|
||||
LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu", part2->size);
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (UE->Initialue_identity_5g_s_TMSI.presence) {
|
||||
@@ -1548,7 +1470,7 @@ static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP,
|
||||
const NR_NG_5G_S_TMSI_t *bs_stmsi = &setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI;
|
||||
if (bs_stmsi->size != 6) {
|
||||
LOG_E(NR_RRC, "wrong ng_5G_S_TMSI size, expected 6, provided %lu", bs_stmsi->size);
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
|
||||
fiveg_s_TMSI = BIT_STRING_to_uint64(bs_stmsi);
|
||||
@@ -1576,18 +1498,12 @@ static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP,
|
||||
}
|
||||
}
|
||||
|
||||
rrc_gNB_process_RRCSetupComplete(ctxt_pP, ue_context_p, setup_complete->criticalExtensions.choice.rrcSetupComplete);
|
||||
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " UE State = NR_RRC_CONNECTED \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||
return 0;
|
||||
rrc_gNB_process_RRCSetupComplete(rrc, UE, setup_complete->criticalExtensions.choice.rrcSetupComplete);
|
||||
return;
|
||||
}
|
||||
|
||||
static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_p,
|
||||
const NR_RRCReconfigurationComplete_t *reconfig_complete)
|
||||
static void handle_rrcReconfigurationComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_RRCReconfigurationComplete_t *reconfig_complete)
|
||||
{
|
||||
AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
|
||||
uint8_t xid = reconfig_complete->rrc_TransactionIdentifier;
|
||||
UE->ue_reconfiguration_counter++;
|
||||
LOG_I(NR_RRC, "UE %d: Receive RRC Reconfiguration Complete message (xid %d)\n", UE->rrc_ue_id, xid);
|
||||
@@ -1595,22 +1511,22 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
|
||||
switch (UE->xids[xid]) {
|
||||
case RRC_PDUSESSION_RELEASE: {
|
||||
gtpv1u_gnb_delete_tunnel_req_t req = {0};
|
||||
gtpv1u_delete_ngu_tunnel(ctxt_pP->instance, &req);
|
||||
gtpv1u_delete_ngu_tunnel(rrc->module_id, &req);
|
||||
// NGAP_PDUSESSION_RELEASE_RESPONSE
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid);
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(rrc, UE, xid);
|
||||
} break;
|
||||
case RRC_PDUSESSION_ESTABLISH:
|
||||
if (UE->n_initial_pdu > 0) {
|
||||
/* PDU sessions through initial UE context setup */
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE);
|
||||
UE->n_initial_pdu = 0;
|
||||
free(UE->initial_pdus);
|
||||
UE->initial_pdus = NULL;
|
||||
} else if (UE->nb_of_pdusessions > 0)
|
||||
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, ue_context_p, xid);
|
||||
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(rrc, UE, xid);
|
||||
break;
|
||||
case RRC_PDUSESSION_MODIFY:
|
||||
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(ctxt_pP, ue_context_p, xid);
|
||||
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(rrc, UE, xid);
|
||||
break;
|
||||
case RRC_REESTABLISH_COMPLETE:
|
||||
case RRC_DEDICATED_RECONF:
|
||||
@@ -1630,42 +1546,45 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
|
||||
}
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
|
||||
const rb_id_t Srb_id,
|
||||
const uint8_t *const Rx_sdu,
|
||||
const sdu_size_t sdu_sizeP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
|
||||
|
||||
static void rrc_gNB_generate_UECapabilityEnquiry(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue)
|
||||
{
|
||||
uint8_t buffer[100];
|
||||
|
||||
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(rrc->module_id), T_INT(0), T_INT(0), T_INT(ue->rrc_ue_id));
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
ue->xids[xid] = RRC_UECAPABILITY_ENQUIRY;
|
||||
int size = do_NR_SA_UECapabilityEnquiry(buffer, xid);
|
||||
LOG_I(NR_RRC, "UE %d: Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d, xid %d)\n", ue->rrc_ue_id, size, xid);
|
||||
|
||||
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
|
||||
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue, DCCH, buffer, size);
|
||||
}
|
||||
|
||||
static int rrc_gNB_decode_dcch(gNB_RRC_INST *rrc, const f1ap_ul_rrc_message_t *msg)
|
||||
{
|
||||
/* we look up by CU UE ID! Do NOT change back to RNTI! */
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, msg->gNB_CU_ue_id);
|
||||
if (!ue_context_p) {
|
||||
LOG_E(RRC, "could not find UE context for CU UE ID %lu, aborting transaction\n", ctxt_pP->rntiMaybeUEid);
|
||||
LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", msg->gNB_CU_ue_id);
|
||||
return -1;
|
||||
}
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
|
||||
if (msg->srb_id < 1 || msg->srb_id > 2) {
|
||||
LOG_E(NR_RRC, "Received message on SRB %d, discarding message\n", msg->srb_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((Srb_id != 1) && (Srb_id != 2)) {
|
||||
LOG_E(NR_RRC, "Received message on SRB%ld, should not have ...\n", Srb_id);
|
||||
} else {
|
||||
LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
|
||||
}
|
||||
|
||||
LOG_D(NR_RRC, "Decoding UL-DCCH Message\n");
|
||||
{
|
||||
for (int i = 0; i < sdu_sizeP; i++) {
|
||||
LOG_T(NR_RRC, "%x.", Rx_sdu[i]);
|
||||
}
|
||||
|
||||
LOG_T(NR_RRC, "\n");
|
||||
}
|
||||
|
||||
LOG_D(NR_RRC, "UE %d: Decoding DCCH %d size %d\n", UE->rrc_ue_id, msg->srb_id, msg->rrc_container_length);
|
||||
LOG_DUMPMSG(RRC, DEBUG_RRC, (char *)msg->rrc_container, msg->rrc_container_length, "[MSG] RRC UL Information Transfer \n");
|
||||
NR_UL_DCCH_Message_t *ul_dcch_msg = NULL;
|
||||
asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_DCCH_Message, (void **)&ul_dcch_msg, Rx_sdu, sdu_sizeP, 0, 0);
|
||||
asn_dec_rval_t dec_rval =
|
||||
uper_decode(NULL, &asn_DEF_NR_UL_DCCH_Message, (void **)&ul_dcch_msg, msg->rrc_container, msg->rrc_container_length, 0, 0);
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
LOG_E(NR_RRC, "Failed to decode UL-DCCH (%zu bytes)\n", dec_rval.consumed);
|
||||
LOG_E(NR_RRC, "UE %d: Failed to decode UL-DCCH (%zu bytes)\n", UE->rrc_ue_id, dec_rval.consumed);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1680,102 +1599,55 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete:
|
||||
handle_rrcReconfigurationComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete);
|
||||
handle_rrcReconfigurationComplete(rrc, UE, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete);
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete:
|
||||
if (handle_rrcSetupComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete) == -1)
|
||||
return -1;
|
||||
handle_rrcSetupComplete(rrc, UE, ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete);
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_measurementReport:
|
||||
DevAssert(ul_dcch_msg != NULL
|
||||
&& ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1
|
||||
&& ul_dcch_msg->message.choice.c1
|
||||
&& ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_measurementReport);
|
||||
rrc_gNB_process_MeasurementReport(ue_context_p, ul_dcch_msg->message.choice.c1->choice.measurementReport);
|
||||
rrc_gNB_process_MeasurementReport(UE, ul_dcch_msg->message.choice.c1->choice.measurementReport);
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
|
||||
LOG_D(NR_RRC, "Recived RRC GNB UL Information Transfer \n");
|
||||
if (!ue_context_p) {
|
||||
LOG_W(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_D(NR_RRC, "[MSG] RRC UL Information Transfer \n");
|
||||
LOG_DUMPMSG(RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] RRC UL Information Transfer \n");
|
||||
|
||||
rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP, ue_context_p, ul_dcch_msg);
|
||||
rrc_gNB_send_NGAP_UPLINK_NAS(rrc, UE, ul_dcch_msg);
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete:
|
||||
// to avoid segmentation fault
|
||||
if (!ue_context_p) {
|
||||
LOG_I(NR_RRC, "Processing securityModeComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_I(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT " received securityModeComplete on UL-DCCH %d from UE\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
DCCH);
|
||||
LOG_D(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT
|
||||
" RLC RB %02d --- RLC_DATA_IND %d bytes "
|
||||
"(securityModeComplete) ---> RRC_eNB\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
DCCH,
|
||||
sdu_sizeP);
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
|
||||
}
|
||||
|
||||
/* configure ciphering */
|
||||
nr_rrc_pdcp_config_security(ctxt_pP, ue_context_p, 1);
|
||||
ue_context_p->ue_context.as_security_active = true;
|
||||
nr_rrc_pdcp_config_security(UE, true);
|
||||
UE->as_security_active = true;
|
||||
|
||||
/* trigger UE capability enquiry if we don't have them yet */
|
||||
if (ue_context_p->ue_context.ue_cap_buffer.len == 0) {
|
||||
rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p);
|
||||
if (UE->ue_cap_buffer.len == 0) {
|
||||
rrc_gNB_generate_UECapabilityEnquiry(rrc, UE);
|
||||
/* else blocks are executed after receiving UE capability info */
|
||||
} else if (ue_context_p->ue_context.n_initial_pdu > 0) {
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
} else if (UE->n_initial_pdu > 0) {
|
||||
/* there were PDU sessions with the NG UE Context setup, but we had
|
||||
* to set up security, so trigger PDU sessions now. The UE NAS
|
||||
* message will be forwarded in the corresponding reconfiguration,
|
||||
* the Initial context setup response after reconfiguration complete. */
|
||||
trigger_bearer_setup(gnb_rrc_inst, UE, UE->n_initial_pdu, UE->initial_pdus, 0);
|
||||
trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0);
|
||||
} else {
|
||||
/* we already have capabilities, and no PDU sessions to setup, ack
|
||||
* this UE */
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
|
||||
rrc_forward_ue_nas_message(RC.nrrrc[0], &ue_context_p->ue_context);
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE);
|
||||
rrc_forward_ue_nas_message(rrc, UE);
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure:
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] NR RRC Security Mode Failure\n");
|
||||
LOG_E(NR_RRC, "UE %d: received securityModeFailure\n", ue_context_p->ue_context.rrc_ue_id);
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
|
||||
}
|
||||
|
||||
LOG_W(NR_RRC, "Cannot continue as no AS security is activated (implementation missing)\n");
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
|
||||
if (handle_ueCapabilityInformation(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation)
|
||||
== -1)
|
||||
return -1;
|
||||
handle_ueCapabilityInformation(rrc, UE, ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation);
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
|
||||
if (handle_rrcReestablishmentComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete)
|
||||
== -1)
|
||||
return -1;
|
||||
handle_rrcReestablishmentComplete(rrc, UE, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1973,8 +1845,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
|
||||
e1_send_bearer_updates(rrc, UE, resp->drbs_to_be_setup_length, resp->drbs_to_be_setup);
|
||||
}
|
||||
|
||||
protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->gNB_CU_ue_id, .module_id = instance};
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(rrc, UE);
|
||||
}
|
||||
|
||||
static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p)
|
||||
@@ -2043,8 +1914,7 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p)
|
||||
static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance)
|
||||
{
|
||||
f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p);
|
||||
protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->gNB_CU_ue_id, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_CU_ue_id);
|
||||
if (!ue_context_p) {
|
||||
LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", resp->gNB_CU_ue_id);
|
||||
@@ -2072,15 +1942,14 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i
|
||||
}
|
||||
UE->masterCellGroup = cellGroupConfig;
|
||||
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(rrc, UE);
|
||||
}
|
||||
}
|
||||
|
||||
static void rrc_CU_process_ue_modification_required(MessageDef *msg_p)
|
||||
static void rrc_CU_process_ue_modification_required(MessageDef *msg_p, instance_t instance)
|
||||
{
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
||||
f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p);
|
||||
protocol_ctxt_t ctxt = {.rntiMaybeUEid = required->gNB_CU_ue_id, .module_id = 0, .instance = 0, .enb_flag = 1, .eNB_index = 0};
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, required->gNB_CU_ue_id);
|
||||
if (ue_context_p == NULL) {
|
||||
LOG_E(RRC, "Could not find UE context for CU UE ID %d, cannot handle UE context modification request\n", required->gNB_CU_ue_id);
|
||||
@@ -2128,8 +1997,7 @@ static void rrc_CU_process_ue_modification_required(MessageDef *msg_p)
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
|
||||
|
||||
/* trigger reconfiguration */
|
||||
nr_rrc_reconfiguration_req(ue_context_p, &ctxt, 0, 0);
|
||||
//rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
|
||||
nr_rrc_reconfiguration_req(rrc, UE, 0, 0);
|
||||
return;
|
||||
}
|
||||
LOG_W(RRC,
|
||||
@@ -2394,7 +2262,6 @@ void *rrc_gnb_task(void *args_p) {
|
||||
MessageDef *msg_p;
|
||||
instance_t instance;
|
||||
int result;
|
||||
protocol_ctxt_t ctxt = {.module_id = 0, .enb_flag = 1, .instance = 0, .rntiMaybeUEid = 0, .frame = -1, .subframe = -1, .eNB_index = 0, .brOption = false};
|
||||
|
||||
long stats_timer_id = 1;
|
||||
if (!IS_SOFTMODEM_NOSTATS_BIT) {
|
||||
@@ -2441,23 +2308,7 @@ void *rrc_gnb_task(void *args_p) {
|
||||
/* Messages from PDCP */
|
||||
/* From DU -> CU */
|
||||
case F1AP_UL_RRC_MESSAGE:
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
|
||||
instance,
|
||||
GNB_FLAG_YES,
|
||||
F1AP_UL_RRC_MESSAGE(msg_p).gNB_CU_ue_id,
|
||||
0,
|
||||
0);
|
||||
LOG_D(NR_RRC,
|
||||
"Decoding DCCH %d: ue %04lx, inst %ld, ctxt %p, size %d\n",
|
||||
F1AP_UL_RRC_MESSAGE(msg_p).srb_id,
|
||||
ctxt.rntiMaybeUEid,
|
||||
instance,
|
||||
&ctxt,
|
||||
F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length);
|
||||
rrc_gNB_decode_dcch(&ctxt,
|
||||
F1AP_UL_RRC_MESSAGE(msg_p).srb_id,
|
||||
F1AP_UL_RRC_MESSAGE(msg_p).rrc_container,
|
||||
F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length);
|
||||
rrc_gNB_decode_dcch(RC.nrrrc[instance], &F1AP_UL_RRC_MESSAGE(msg_p));
|
||||
free(F1AP_UL_RRC_MESSAGE(msg_p).rrc_container);
|
||||
break;
|
||||
|
||||
@@ -2492,7 +2343,7 @@ void *rrc_gnb_task(void *args_p) {
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED:
|
||||
rrc_CU_process_ue_modification_required(msg_p);
|
||||
rrc_CU_process_ue_modification_required(msg_p, instance);
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_RELEASE_REQ:
|
||||
@@ -2585,53 +2436,24 @@ void *rrc_gnb_task(void *args_p) {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void rrc_gNB_generate_SecurityModeCommand(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP)
|
||||
void rrc_gNB_generate_SecurityModeCommand(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
uint8_t buffer[100];
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
AssertFatal(!ue_p->as_security_active, "logic error: security already active\n");
|
||||
|
||||
T(T_ENB_RRC_SECURITY_MODE_COMMAND,
|
||||
T_INT(ctxt_pP->module_id),
|
||||
T_INT(ctxt_pP->frame),
|
||||
T_INT(ctxt_pP->subframe),
|
||||
T_INT(ctxt_pP->rntiMaybeUEid));
|
||||
T(T_ENB_RRC_SECURITY_MODE_COMMAND, T_INT(0), T_INT(0), T_INT(0), T_INT(ue_p->rrc_ue_id));
|
||||
NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_p->integrity_algorithm;
|
||||
int size = do_NR_SecurityModeCommand(ctxt_pP,
|
||||
buffer,
|
||||
rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
|
||||
int size = do_NR_SecurityModeCommand(buffer,
|
||||
rrc_gNB_get_next_transaction_identifier(rrc->module_id),
|
||||
ue_p->ciphering_algorithm,
|
||||
integrity_algorithm);
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Security Mode Command\n");
|
||||
LOG_I(NR_RRC, "UE %u Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", ue_p->rrc_ue_id, size);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
|
||||
}
|
||||
|
||||
void
|
||||
rrc_gNB_generate_UECapabilityEnquiry(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
uint8_t buffer[100];
|
||||
|
||||
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rntiMaybeUEid));
|
||||
gNB_RRC_UE_t *ue = &ue_context_pP->ue_context;
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
ue->xids[xid] = RRC_UECAPABILITY_ENQUIRY;
|
||||
int size = do_NR_SA_UECapabilityEnquiry(ctxt_pP, buffer, xid);
|
||||
LOG_I(NR_RRC, "UE %d: Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d, xid %d)\n", ue->rrc_ue_id, size, xid);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
|
||||
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue, DCCH, buffer, size);
|
||||
}
|
||||
|
||||
typedef struct deliver_ue_ctxt_release_data_t {
|
||||
gNB_RRC_INST *rrc;
|
||||
f1ap_ue_context_release_cmd_t *release_cmd;
|
||||
@@ -2651,23 +2473,13 @@ static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_i
|
||||
* Generate the RRC Connection Release to UE.
|
||||
* If received, UE should switch to RRC_IDLE mode.
|
||||
*/
|
||||
void
|
||||
rrc_gNB_generate_RRCRelease(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
void rrc_gNB_generate_RRCRelease(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
|
||||
{
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
|
||||
int size = do_NR_RRCRelease(buffer, NR_RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id));
|
||||
int size = do_NR_RRCRelease(buffer, NR_RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(rrc->module_id));
|
||||
|
||||
LOG_I(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCRelease (bytes %d)\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
size);
|
||||
LOG_I(NR_RRC, "UE %d: Generate RRCRelease (bytes %d)\n", UE->rrc_ue_id, size);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
const gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
|
||||
RETURN_IF_INVALID_ASSOC_ID(ue_data.du_assoc_id);
|
||||
f1ap_ue_context_release_cmd_t ue_context_release_cmd = {
|
||||
@@ -2678,7 +2490,7 @@ rrc_gNB_generate_RRCRelease(
|
||||
.srb_id = DCCH,
|
||||
};
|
||||
deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd, .assoc_id = ue_data.du_assoc_id};
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data);
|
||||
nr_pdcp_data_req_srb(UE->rrc_ue_id, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data);
|
||||
}
|
||||
|
||||
int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint32_t tmsi, uint8_t paging_drx)
|
||||
|
||||
@@ -44,29 +44,25 @@
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, uint8_t *inde_list)
|
||||
int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(gNB_RRC_UE_t *ue,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list)
|
||||
{
|
||||
if (!create_tunnel_resp_pP) {
|
||||
LOG_E(NR_RRC, "create_tunnel_resp_pP error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels);
|
||||
/* we look up by CU UE ID! Do NOT change back to RNTI! */
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
|
||||
if (!ue_context_p) {
|
||||
LOG_E(NR_RRC, "UE table error\n");
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
|
||||
ue_context_p->ue_context.nsa_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
|
||||
ue_context_p->ue_context.nsa_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
|
||||
ue_context_p->ue_context.nsa_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i];
|
||||
ue->nsa_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
|
||||
ue->nsa_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
|
||||
ue->nsa_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i];
|
||||
LOG_I(RRC,
|
||||
PROTOCOL_RRC_CTXT_UE_FMT " rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
"UE %d: rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp "
|
||||
"addr len %d \n",
|
||||
ue->rrc_ue_id,
|
||||
create_tunnel_resp_pP->enb_S1u_teid[i],
|
||||
ue_context_p->ue_context.nsa_gtp_teid[inde_list[i]],
|
||||
ue->nsa_gtp_teid[inde_list[i]],
|
||||
inde_list[i],
|
||||
i,
|
||||
create_tunnel_resp_pP->eps_bearer_id[i],
|
||||
|
||||
@@ -30,12 +30,8 @@
|
||||
#ifndef RRC_GNB_GTPV1U_H_
|
||||
#define RRC_GNB_GTPV1U_H_
|
||||
|
||||
|
||||
int
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
);
|
||||
int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(gNB_RRC_UE_t *ue,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list);
|
||||
|
||||
#endif
|
||||
|
||||
+114
-205
@@ -93,51 +93,34 @@ static const uint16_t NGAP_INTEGRITY_NIA3_MASK = 0x2000;
|
||||
|
||||
#define INTEGRITY_ALGORITHM_NONE NR_IntegrityProtAlgorithm_nia0
|
||||
|
||||
static int rrc_gNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, ngap_security_capabilities_t *security_capabilities_pP);
|
||||
static void set_UE_security_algos(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const ngap_security_capabilities_t *cap);
|
||||
|
||||
/*! \fn void process_gNB_security_key (const protocol_ctxt_t* const ctxt_pP, eNB_RRC_UE_t * const ue_context_pP, uint8_t *security_key)
|
||||
/*!
|
||||
*\brief save security key.
|
||||
*\param ctxt_pP Running context.
|
||||
*\param ue_context_pP UE context.
|
||||
*\param UE UE context.
|
||||
*\param security_key_pP The security key received from NGAP.
|
||||
*/
|
||||
//------------------------------------------------------------------------------
|
||||
void process_gNB_security_key (
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t *security_key_pP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
static void set_UE_security_key(gNB_RRC_UE_t *UE, uint8_t *security_key_pP)
|
||||
{
|
||||
char ascii_buffer[65];
|
||||
uint8_t i;
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
int i;
|
||||
|
||||
/* Saves the security key */
|
||||
memcpy(UE->kgnb, security_key_pP, SECURITY_KEY_LENGTH);
|
||||
memset(UE->nh, 0, SECURITY_KEY_LENGTH);
|
||||
UE->nh_ncc = -1;
|
||||
|
||||
char ascii_buffer[65];
|
||||
for (i = 0; i < 32; i++) {
|
||||
sprintf(&ascii_buffer[2 * i], "%02X", UE->kgnb[i]);
|
||||
}
|
||||
ascii_buffer[2 * 1] = '\0';
|
||||
|
||||
ascii_buffer[2 * i] = '\0';
|
||||
LOG_I(NR_RRC, "[gNB %d][UE %x] Saved security key %s\n", ctxt_pP->module_id, UE->rnti, ascii_buffer);
|
||||
LOG_I(NR_RRC, "[UE %x] Saved security key %s\n", UE->rnti, ascii_buffer);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
nr_rrc_pdcp_config_security(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const uint8_t enable_ciphering
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
void nr_rrc_pdcp_config_security(gNB_RRC_UE_t *UE, bool enable_ciphering)
|
||||
{
|
||||
//uint8_t *k_kdf = NULL;
|
||||
static int print_keys= 1;
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
|
||||
/* Derive the keys from kgnb */
|
||||
nr_pdcp_entity_security_keys_and_algos_t security_parameters;
|
||||
@@ -157,33 +140,24 @@ nr_rrc_pdcp_config_security(
|
||||
}
|
||||
}
|
||||
|
||||
nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, true, &security_parameters);
|
||||
nr_pdcp_config_set_security(UE->rrc_ue_id, DCCH, true, &security_parameters);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Initial UE NAS message on S1AP.
|
||||
*/
|
||||
void
|
||||
rrc_gNB_send_NGAP_NAS_FIRST_REQ(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
NR_RRCSetupComplete_IEs_t *rrcSetupComplete
|
||||
)
|
||||
void rrc_gNB_send_NGAP_NAS_FIRST_REQ(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRCSetupComplete_IEs_t *rrcSetupComplete)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
// gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
MessageDef *message_p = NULL;
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_NAS_FIRST_REQ);
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_RRC_GNB, rrc->module_id, NGAP_NAS_FIRST_REQ);
|
||||
ngap_nas_first_req_t *req = &NGAP_NAS_FIRST_REQ(message_p);
|
||||
memset(req, 0, sizeof(*req));
|
||||
|
||||
req->gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||
|
||||
/* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */
|
||||
AssertFatal(UE->establishment_cause < NGAP_RRC_CAUSE_LAST, "Establishment cause invalid (%jd/%d) for gNB %d!", UE->establishment_cause, NGAP_RRC_CAUSE_LAST, ctxt_pP->module_id);
|
||||
AssertFatal(UE->establishment_cause < NGAP_RRC_CAUSE_LAST, "Establishment cause invalid (%jd/%d)!", UE->establishment_cause, NGAP_RRC_CAUSE_LAST);
|
||||
req->establishment_cause = UE->establishment_cause;
|
||||
|
||||
/* Forward NAS message */
|
||||
@@ -224,8 +198,7 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ(
|
||||
UE->ue_guami.amf_pointer = req->ue_identity.guami.amf_pointer;
|
||||
|
||||
LOG_I(NGAP,
|
||||
"[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n",
|
||||
ctxt_pP->module_id,
|
||||
"Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n",
|
||||
req->ue_identity.guami.amf_set_id,
|
||||
req->ue_identity.guami.amf_region_id,
|
||||
UE->rnti);
|
||||
@@ -233,7 +206,7 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ(
|
||||
req->ue_identity.presenceMask = NGAP_UE_IDENTITIES_NONE;
|
||||
}
|
||||
|
||||
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, message_p);
|
||||
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, message_p);
|
||||
}
|
||||
|
||||
static void fill_qos(NGAP_QosFlowSetupRequestList_t *qos, pdusession_t *session)
|
||||
@@ -441,7 +414,6 @@ void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
|
||||
int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t instance)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
ngap_initial_context_setup_req_t *req = &NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p);
|
||||
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id);
|
||||
@@ -457,7 +429,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
|
||||
itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p);
|
||||
return (-1);
|
||||
}
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
||||
UE->amf_ue_ngap_id = req->amf_ue_ngap_id;
|
||||
|
||||
/* store guami in gNB_RRC_UE_t context;
|
||||
@@ -473,14 +445,6 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
|
||||
// this is malloced pointers, we pass it for later free()
|
||||
UE->nas_pdu = req->nas_pdu;
|
||||
|
||||
/* security */
|
||||
rrc_gNB_process_security(&ctxt, ue_context_p, &req->security_capabilities);
|
||||
process_gNB_security_key(&ctxt, ue_context_p, req->security_key);
|
||||
|
||||
/* configure only integrity, ciphering comes after receiving SecurityModeComplete */
|
||||
nr_rrc_pdcp_config_security(&ctxt, ue_context_p, 0);
|
||||
|
||||
rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p);
|
||||
if (req->nb_of_pdusessions > 0) {
|
||||
/* if there are PDU sessions to setup, store them to be created once
|
||||
* security (and UE capabilities) are received */
|
||||
@@ -491,6 +455,35 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
|
||||
UE->initial_pdus[i] = req->pdusession_param[i];
|
||||
}
|
||||
|
||||
/* security */
|
||||
set_UE_security_algos(rrc, UE, &req->security_capabilities);
|
||||
set_UE_security_key(UE, req->security_key);
|
||||
|
||||
/* TS 38.413: "store the received Security Key in the UE context and, if the
|
||||
* NG-RAN node is required to activate security for the UE, take this
|
||||
* security key into use.": I interpret this as "if AS security is already
|
||||
* active, don't do anything" */
|
||||
if (!UE->as_security_active) {
|
||||
/* configure only integrity, ciphering comes after receiving SecurityModeComplete */
|
||||
nr_rrc_pdcp_config_security(UE, false);
|
||||
rrc_gNB_generate_SecurityModeCommand(rrc, UE);
|
||||
} else {
|
||||
/* if AS security key is active, we also have the UE capabilities. Then,
|
||||
* there are two possibilities: we should set up PDU sessions, and/or
|
||||
* forward the NAS message. */
|
||||
if (req->nb_of_pdusessions > 0) {
|
||||
// do not remove the above allocation which is reused here: this is used
|
||||
// in handle_rrcReconfigurationComplete() to know that we need to send a
|
||||
// Initial context setup response message
|
||||
trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0);
|
||||
} else {
|
||||
/* no PDU sesion to setup: acknowledge this message, and forward NAS
|
||||
* message, if required */
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE);
|
||||
rrc_forward_ue_nas_message(rrc, UE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef E2_AGENT
|
||||
signal_rrc_state_changed_to(UE, RC_SM_RRC_CONNECTED);
|
||||
#endif
|
||||
@@ -498,16 +491,13 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP)
|
||||
//------------------------------------------------------------------------------
|
||||
void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
|
||||
{
|
||||
MessageDef *msg_p = NULL;
|
||||
int pdu_sessions_done = 0;
|
||||
int pdu_sessions_failed = 0;
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, NGAP_INITIAL_CONTEXT_SETUP_RESP);
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_ENB, rrc->module_id, NGAP_INITIAL_CONTEXT_SETUP_RESP);
|
||||
ngap_initial_context_setup_resp_t *resp = &NGAP_INITIAL_CONTEXT_SETUP_RESP(msg_p);
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
|
||||
resp->gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||
|
||||
@@ -538,14 +528,11 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c
|
||||
|
||||
resp->nb_of_pdusessions = pdu_sessions_done;
|
||||
resp->nb_of_pdusessions_failed = pdu_sessions_failed;
|
||||
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
|
||||
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
|
||||
}
|
||||
|
||||
static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint16_t algorithms)
|
||||
static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(const gNB_RRC_INST *rrc, uint16_t algorithms)
|
||||
{
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
int i;
|
||||
/* preset nea0 as fallback */
|
||||
int ret = 0;
|
||||
@@ -577,11 +564,8 @@ static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(
|
||||
return ret;
|
||||
}
|
||||
|
||||
static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint16_t algorithms)
|
||||
static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(const gNB_RRC_INST *rrc, uint16_t algorithms)
|
||||
{
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
int i;
|
||||
/* preset nia0 as fallback */
|
||||
int ret = 0;
|
||||
@@ -613,58 +597,38 @@ static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rrc_gNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, ngap_security_capabilities_t *security_capabilities_pP)
|
||||
/*
|
||||
* \brief set security algorithms
|
||||
* \param rrc pointer to RRC context
|
||||
* \param UE UE context
|
||||
* \param cap security capabilities for this UE
|
||||
*/
|
||||
static void set_UE_security_algos(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const ngap_security_capabilities_t *cap)
|
||||
{
|
||||
bool changed = false;
|
||||
NR_CipheringAlgorithm_t cipheringAlgorithm;
|
||||
e_NR_IntegrityProtAlgorithm integrityProtAlgorithm;
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
|
||||
/* Save security parameters */
|
||||
UE->security_capabilities = *security_capabilities_pP;
|
||||
// translation
|
||||
LOG_D(NR_RRC,
|
||||
"[gNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n",
|
||||
ctxt_pP->module_id,
|
||||
UE->security_capabilities.nRencryption_algorithms,
|
||||
(unsigned long)UE->ciphering_algorithm,
|
||||
UE->security_capabilities.nRintegrity_algorithms,
|
||||
UE->integrity_algorithm);
|
||||
UE->security_capabilities = *cap;
|
||||
|
||||
/* Select relevant algorithms */
|
||||
cipheringAlgorithm = rrc_gNB_select_ciphering(ctxt_pP, UE->security_capabilities.nRencryption_algorithms);
|
||||
NR_CipheringAlgorithm_t cipheringAlgorithm = rrc_gNB_select_ciphering(rrc, cap->nRencryption_algorithms);
|
||||
e_NR_IntegrityProtAlgorithm integrityProtAlgorithm = rrc_gNB_select_integrity(rrc, cap->nRintegrity_algorithms);
|
||||
|
||||
if (UE->ciphering_algorithm != cipheringAlgorithm) {
|
||||
UE->ciphering_algorithm = cipheringAlgorithm;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
integrityProtAlgorithm = rrc_gNB_select_integrity(ctxt_pP, UE->security_capabilities.nRintegrity_algorithms);
|
||||
|
||||
if (UE->integrity_algorithm != integrityProtAlgorithm) {
|
||||
UE->integrity_algorithm = integrityProtAlgorithm;
|
||||
changed = true;
|
||||
}
|
||||
UE->ciphering_algorithm = cipheringAlgorithm;
|
||||
UE->integrity_algorithm = integrityProtAlgorithm;
|
||||
|
||||
LOG_I(NR_RRC,
|
||||
"[gNB %d][UE %d] Selected security algorithms (%p): ciphering %lx, integrity %x (algorithms %s)\n",
|
||||
ctxt_pP->module_id,
|
||||
"[UE %d] Selected security algorithms: ciphering %lx, integrity %x\n",
|
||||
UE->rrc_ue_id,
|
||||
security_capabilities_pP,
|
||||
cipheringAlgorithm,
|
||||
integrityProtAlgorithm,
|
||||
changed ? "changed" : "are the same");
|
||||
return changed;
|
||||
integrityProtAlgorithm);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mui_t *rrc_gNB_mui)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
uint32_t length;
|
||||
uint8_t buffer[4096];
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
ngap_downlink_nas_t *req = &NGAP_DOWNLINK_NAS(msg_p);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_ue_ngap_id);
|
||||
|
||||
if (ue_context_p == NULL) {
|
||||
/* Can not associate this message to an UE index, send a failure to NGAP and discard it! */
|
||||
@@ -681,71 +645,44 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu
|
||||
}
|
||||
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
|
||||
|
||||
/* Create message for PDCP (DLInformationTransfer_t) */
|
||||
length = do_NR_DLInformationTransfer(buffer,
|
||||
sizeof(buffer),
|
||||
rrc_gNB_get_next_transaction_identifier(instance),
|
||||
req->nas_pdu.length,
|
||||
req->nas_pdu.buffer);
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, buffer, length, "[MSG] RRC DL Information Transfer\n");
|
||||
/*
|
||||
* switch UL or DL NAS message without RRC piggybacked to SRB2 if active.
|
||||
*/
|
||||
AssertFatal(!NODE_IS_DU(RC.nrrrc[ctxt.module_id]->node_type), "illegal node type DU: receiving NGAP messages at this node\n");
|
||||
/* Transfer data to PDCP */
|
||||
rb_id_t srb_id = UE->Srb[2].Active ? DCCH1 : DCCH;
|
||||
nr_rrc_transfer_protected_rrc_message(RC.nrrrc[instance], UE, srb_id, buffer, length);
|
||||
UE->nas_pdu = req->nas_pdu;
|
||||
rrc_forward_ue_nas_message(rrc, UE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_send_NGAP_UPLINK_NAS(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
NR_UL_DCCH_Message_t *const ul_dcch_msg
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
void rrc_gNB_send_NGAP_UPLINK_NAS(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UL_DCCH_Message_t *const ul_dcch_msg)
|
||||
{
|
||||
MessageDef *msg_p;
|
||||
NR_ULInformationTransfer_t *ulInformationTransfer = ul_dcch_msg->message.choice.c1->choice.ulInformationTransfer;
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
NR_ULInformationTransfer_t *ulInformationTransfer = ul_dcch_msg->message.choice.c1->choice.ulInformationTransfer;
|
||||
|
||||
if (ulInformationTransfer->criticalExtensions.present == NR_ULInformationTransfer__criticalExtensions_PR_ulInformationTransfer) {
|
||||
NR_DedicatedNAS_Message_t *nas = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message;
|
||||
uint8_t *buf = malloc(nas->size);
|
||||
AssertFatal(buf != NULL, "out of memory\n");
|
||||
memcpy(buf, nas->buf, nas->size);
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UPLINK_NAS);
|
||||
NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||
NGAP_UPLINK_NAS (msg_p).nas_pdu.length = nas->size;
|
||||
NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer = buf;
|
||||
// extract_imsi(NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer,
|
||||
// NGAP_UPLINK_NAS (msg_p).nas_pdu.length,
|
||||
// ue_context_pP);
|
||||
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
|
||||
LOG_D(NR_RRC,"Send RRC GNB UL Information Transfer \n");
|
||||
}
|
||||
NR_ULInformationTransfer__criticalExtensions_PR p = ulInformationTransfer->criticalExtensions.present;
|
||||
if (p != NR_ULInformationTransfer__criticalExtensions_PR_ulInformationTransfer) {
|
||||
LOG_E(NR_RRC, "UE %d: expected presence of ulInformationTransfer, but message has %d\n", UE->rrc_ue_id, p);
|
||||
return;
|
||||
}
|
||||
|
||||
NR_DedicatedNAS_Message_t *nas = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message;
|
||||
if (!nas) {
|
||||
LOG_E(NR_RRC, "UE %d: expected NAS message in ulInformation, but it is NULL\n", UE->rrc_ue_id);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *buf = malloc_or_fail(nas->size);
|
||||
memcpy(buf, nas->buf, nas->size);
|
||||
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, rrc->module_id, NGAP_UPLINK_NAS);
|
||||
NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||
NGAP_UPLINK_NAS(msg_p).nas_pdu.length = nas->size;
|
||||
NGAP_UPLINK_NAS(msg_p).nas_pdu.buffer = buf;
|
||||
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
void rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid)
|
||||
{
|
||||
MessageDef *msg_p;
|
||||
int pdu_sessions_done = 0;
|
||||
int pdu_sessions_failed = 0;
|
||||
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP);
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_GNB, rrc->module_id, NGAP_PDUSESSION_SETUP_RESP);
|
||||
ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_p);
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
resp->gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||
|
||||
for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) {
|
||||
@@ -792,7 +729,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
|
||||
if ((pdu_sessions_done > 0 || pdu_sessions_failed)) {
|
||||
LOG_I(NR_RRC, "NGAP_PDUSESSION_SETUP_RESP: sending the message\n");
|
||||
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
|
||||
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
|
||||
}
|
||||
|
||||
for(int i = 0; i < NB_RB_MAX; i++) {
|
||||
@@ -806,13 +743,11 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
protocol_ctxt_t ctxt={0};
|
||||
|
||||
ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], msg->gNB_ue_ngap_id);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
||||
|
||||
if (ue_context_p == NULL) {
|
||||
MessageDef *msg_fail_p = NULL;
|
||||
@@ -946,18 +881,16 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
|
||||
{
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
|
||||
protocol_ctxt_t ctxt;
|
||||
ngap_pdusession_modify_req_t *req = &NGAP_PDUSESSION_MODIFY_REQ(msg_p);
|
||||
|
||||
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
||||
ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_ue_ngap_id);
|
||||
if (ue_context_p == NULL) {
|
||||
LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_MODIFY_REQ: unknown UE from NGAP ids (%u)\n", instance, req->gNB_ue_ngap_id);
|
||||
// TO implement return setup failed
|
||||
return (-1);
|
||||
}
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
|
||||
ctxt.eNB_index = 0;
|
||||
bool all_failed = true;
|
||||
for (int i = 0; i < req->nb_pdusessions_tomodify; i++) {
|
||||
rrc_pdu_session_param_t *sess;
|
||||
@@ -992,8 +925,7 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
|
||||
}
|
||||
|
||||
if (!all_failed) {
|
||||
LOG_D(NR_RRC, "generate RRCReconfiguration \n");
|
||||
rrc_gNB_modify_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
|
||||
rrc_gNB_modify_dedicatedRRCReconfiguration(rrc, UE);
|
||||
} else {
|
||||
LOG_I(NR_RRC,
|
||||
"pdu session modify failed, fill NGAP_PDUSESSION_MODIFY_RESP with the pdu session information that failed to modify \n");
|
||||
@@ -1018,21 +950,13 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
|
||||
return (0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid)
|
||||
{
|
||||
MessageDef *msg_p = NULL;
|
||||
uint8_t pdu_sessions_failed = 0;
|
||||
uint8_t pdu_sessions_done = 0;
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP);
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_GNB, rrc->module_id, NGAP_PDUSESSION_MODIFY_RESP);
|
||||
if (msg_p == NULL) {
|
||||
LOG_E(NR_RRC, "itti_alloc_new_message failed, msg_p is NULL \n");
|
||||
return (-1);
|
||||
@@ -1099,7 +1023,7 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(
|
||||
|
||||
if (pdu_sessions_done > 0 || pdu_sessions_failed > 0) {
|
||||
LOG_D(NR_RRC, "NGAP_PDUSESSION_MODIFY_RESP: sending the message (total pdu session %d)\n", UE->nb_of_pdusessions);
|
||||
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
|
||||
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
|
||||
} else {
|
||||
itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
|
||||
}
|
||||
@@ -1166,7 +1090,6 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
|
||||
{
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||
uint32_t gNB_ue_ngap_id = 0;
|
||||
protocol_ctxt_t ctxt;
|
||||
gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id;
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id);
|
||||
|
||||
@@ -1199,9 +1122,7 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
|
||||
/* special case: the DU might be offline, in which case the f1_ue_data exists
|
||||
* but is set to 0 */
|
||||
if (cu_exists_f1_ue_data(UE->rrc_ue_id) && cu_get_f1_ue_data(UE->rrc_ue_id).du_assoc_id != 0) {
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
|
||||
ctxt.eNB_index = 0;
|
||||
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
|
||||
rrc_gNB_generate_RRCRelease(rrc, UE);
|
||||
|
||||
/* UE will be freed after UE context release complete */
|
||||
} else {
|
||||
@@ -1226,19 +1147,16 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
itti_send_msg_to_task(TASK_NGAP, instance, msg);
|
||||
}
|
||||
|
||||
void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const NR_UECapabilityInformation_t *const ue_cap_info)
|
||||
void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UECapabilityInformation_t *const ue_cap_info)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
NR_UE_CapabilityRAT_ContainerList_t *ueCapabilityRATContainerList =
|
||||
ue_cap_info->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList;
|
||||
void *buf;
|
||||
NR_UERadioAccessCapabilityInformation_t rac = {0};
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
|
||||
if (ueCapabilityRATContainerList->list.count == 0) {
|
||||
LOG_W(RRC, "[gNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, UE->rnti);
|
||||
LOG_W(RRC, "[UE %d] bad UE capabilities\n", UE->rrc_ue_id);
|
||||
}
|
||||
|
||||
int ret = uper_encode_to_new_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, &buf);
|
||||
@@ -1259,29 +1177,21 @@ void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP,
|
||||
;
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UERadioAccessCapabilityInformation, &rac);
|
||||
MessageDef *msg_p;
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UE_CAPABILITIES_IND);
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_GNB, rrc->module_id, NGAP_UE_CAPABILITIES_IND);
|
||||
ngap_ue_cap_info_ind_t *ind = &NGAP_UE_CAPABILITIES_IND(msg_p);
|
||||
memset(ind, 0, sizeof(*ind));
|
||||
ind->gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||
ind->ue_radio_cap.length = encoded;
|
||||
ind->ue_radio_cap.buffer = buf2;
|
||||
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
|
||||
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
|
||||
LOG_I(NR_RRC,"Send message to ngap: NGAP_UE_CAPABILITIES_IND\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid)
|
||||
{
|
||||
int pdu_sessions_released = 0;
|
||||
MessageDef *msg_p;
|
||||
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_RELEASE_RESPONSE);
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_GNB, rrc->module_id, NGAP_PDUSESSION_RELEASE_RESPONSE);
|
||||
ngap_pdusession_release_resp_t *resp = &NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p);
|
||||
memset(resp, 0, sizeof(*resp));
|
||||
resp->gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||
@@ -1300,7 +1210,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
|
||||
resp->nb_of_pdusessions_released = pdu_sessions_released;
|
||||
resp->nb_of_pdusessions_failed = 0;
|
||||
LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: rrc_ue_id %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released);
|
||||
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
|
||||
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -1308,14 +1218,14 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
protocol_ctxt_t ctxt;
|
||||
ngap_pdusession_release_command_t *cmd = &NGAP_PDUSESSION_RELEASE_COMMAND(msg_p);
|
||||
gNB_ue_ngap_id = cmd->gNB_ue_ngap_id;
|
||||
if (cmd->nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) {
|
||||
LOG_E(NR_RRC, "incorrect number of pdu session do release %d\n", cmd->nb_pdusessions_torelease);
|
||||
return -1;
|
||||
}
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, gNB_ue_ngap_id);
|
||||
|
||||
if (!ue_context_p) {
|
||||
LOG_E(NR_RRC, "[gNB %ld] not found ue context gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id);
|
||||
@@ -1324,11 +1234,10 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
|
||||
|
||||
LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
|
||||
LOG_I(
|
||||
NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu rrc_ue_id %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease);
|
||||
bool found = false;
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id);
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
UE->xids[xid] = RRC_PDUSESSION_RELEASE;
|
||||
for (int pdusession = 0; pdusession < cmd->nb_pdusessions_torelease; pdusession++) {
|
||||
rrc_pdu_session_param_t *pduSession = find_pduSession(UE, cmd->pdusession_release_params[pdusession].pdusession_id, false);
|
||||
@@ -1356,15 +1265,15 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
|
||||
if (found) {
|
||||
// TODO RRCReconfiguration To UE
|
||||
LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n");
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, cmd->nas_pdu.length, cmd->nas_pdu.buffer);
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration_release(rrc, UE, xid, cmd->nas_pdu.length, cmd->nas_pdu.buffer);
|
||||
} else {
|
||||
// gtp tunnel delete
|
||||
LOG_I(NR_RRC, "gtp tunnel delete all tunnels for UE %04x\n", UE->rnti);
|
||||
gtpv1u_gnb_delete_tunnel_req_t req = {0};
|
||||
req.ue_id = UE->rnti;
|
||||
gtpv1u_delete_ngu_tunnel(instance, &req);
|
||||
gtpv1u_delete_ngu_tunnel(rrc->module_id, &req);
|
||||
// NGAP_PDUSESSION_RELEASE_RESPONSE
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(rrc, UE, xid);
|
||||
LOG_I(NR_RRC, "Send PDU Session Release Response \n");
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -40,53 +40,25 @@
|
||||
#include "NR_UL-DCCH-Message.h"
|
||||
#include "NGAP_CauseRadioNetwork.h"
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_NAS_FIRST_REQ(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
NR_RRCSetupComplete_IEs_t *rrcSetupComplete
|
||||
);
|
||||
void rrc_gNB_send_NGAP_NAS_FIRST_REQ(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRCSetupComplete_IEs_t *rrcSetupComplete);
|
||||
|
||||
int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
);
|
||||
void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE);
|
||||
|
||||
int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mui_t *rrc_gNB_mui);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_UPLINK_NAS(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
NR_UL_DCCH_Message_t *const ul_dcch_msg
|
||||
);
|
||||
void rrc_gNB_send_NGAP_UPLINK_NAS(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UL_DCCH_Message_t *const ul_dcch_msg);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid
|
||||
);
|
||||
void rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid);
|
||||
|
||||
void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
int
|
||||
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid
|
||||
);
|
||||
int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid);
|
||||
|
||||
void
|
||||
rrc_gNB_modify_dedicatedRRCReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP
|
||||
);
|
||||
void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p);
|
||||
|
||||
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, const rrc_gNB_ue_context_t *const ue_context_pP, const ngap_Cause_t causeP, const long cause_valueP);
|
||||
|
||||
@@ -99,25 +71,13 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
int num_pdu,
|
||||
uint32_t pdu_session_id[256]);
|
||||
|
||||
void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const NR_UECapabilityInformation_t *const ue_cap_info);
|
||||
void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UECapabilityInformation_t *const ue_cap_info);
|
||||
|
||||
int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t xid
|
||||
);
|
||||
void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid);
|
||||
|
||||
void
|
||||
nr_rrc_pdcp_config_security(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const uint8_t send_security_mode_command
|
||||
);
|
||||
void nr_rrc_pdcp_config_security(gNB_RRC_UE_t *UE, bool enable_ciphering);
|
||||
|
||||
int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "uper_decoder.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_GTPV1U.h"
|
||||
#include "openair2/F1AP/f1ap_ids.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "executables/nr-softmodem.h"
|
||||
@@ -282,15 +282,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
|
||||
create_tunnel_req.rnti = ue_context_p->ue_context.rrc_ue_id;
|
||||
create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded;
|
||||
RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id);
|
||||
memset(&create_tunnel_resp, 0, sizeof(create_tunnel_resp));
|
||||
if (!IS_SOFTMODEM_NOS1) {
|
||||
LOG_D(RRC, "Calling gtpv1u_create_s1u_tunnel()\n");
|
||||
gtpv1u_create_s1u_tunnel(ctxt.instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb);
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
&ctxt,
|
||||
&create_tunnel_resp,
|
||||
&inde_list[0]);
|
||||
gtpv1u_create_s1u_tunnel(rrc->module_id, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb);
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ue_context_p->ue_context, &create_tunnel_resp, &inde_list[0]);
|
||||
}
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).target_assoc_id = m->target_assoc_id;
|
||||
|
||||
@@ -572,17 +572,18 @@ static int nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si)
|
||||
// Dump contents
|
||||
if (si->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_systemInformation ||
|
||||
si->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r16) {
|
||||
LOG_D( RRC, "[UE] si->criticalExtensions.choice.NR_SystemInformation_t->sib_TypeAndInfo.list.count %d\n",
|
||||
si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count );
|
||||
LOG_D(NR_RRC,
|
||||
"[UE] si->criticalExtensions.choice.NR_SystemInformation_t->sib_TypeAndInfo.list.count %d\n",
|
||||
si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count);
|
||||
} else {
|
||||
LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel16)\n" );
|
||||
LOG_D(NR_RRC, "[UE] Unknown criticalExtension version (not Rel16)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) {
|
||||
SystemInformation_IEs__sib_TypeAndInfo__Member *typeandinfo;
|
||||
typeandinfo = si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.array[i];
|
||||
LOG_I(RRC, "Found SIB%d\n", typeandinfo->present + 1);
|
||||
LOG_I(NR_RRC, "Found SIB%d\n", typeandinfo->present + 1);
|
||||
switch(typeandinfo->present) {
|
||||
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2:
|
||||
if(!SI_info->sib2)
|
||||
@@ -679,6 +680,8 @@ static int nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si)
|
||||
if(!SI_info->SInfo_r17.sib19)
|
||||
SI_info->SInfo_r17.sib19 = calloc(1, sizeof(*SI_info->SInfo_r17.sib19));
|
||||
asn_copy(&asn_DEF_NR_SIB19_r17, (void **) &SI_info->SInfo_r17.sib19, typeandinfo->choice.sib19_v1700);
|
||||
if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG)
|
||||
xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)SI_info->SInfo_r17.sib19);
|
||||
nr_timer_start(&SI_info->SInfo_r17.sib19_timer);
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user