diff --git a/CMakeLists.txt b/CMakeLists.txt index 948f623f2b52b73199585adfea9895d64a145c2f..2d916eba8962d1f894ebd2ec9b0aa3b5043c870e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1403,9 +1403,6 @@ if(E2_AGENT) endif() -add_library(MAC_NR ${MAC_NR_SRC}) -target_link_libraries(MAC_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) - add_library(MAC_UE_NR ${MAC_NR_SRC_UE}) target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) @@ -2233,7 +2230,7 @@ add_executable(nr_dlsim ${PHY_INTERFACE_DIR}/queue_t.c ) target_link_libraries(nr_dlsim PRIVATE - -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group m pthread ${T_LIB} ITTI dl shlib_loader ) target_link_libraries(nr_dlsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2277,7 +2274,7 @@ if (ENABLE_LDPC_T1) endif() target_link_libraries(nr_ulsim PRIVATE - -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group m pthread ${T_LIB} ITTI dl shlib_loader ) target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2339,7 +2336,7 @@ if (${T_TRACER}) NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB MISC_NFAPI_NR_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX - L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR ngap + L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_UE_NR ngap CN_UTILS GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE NB_IoT SIMU SIMU_ETH OPENAIR0_LIB ldpc_orig ldpc_optim ldpc_optim8seg ldpc dfts) if (TARGET ${i}) diff --git a/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml index 5b6e03db16f6b3c6df006a138db739883b6107c0..8e353b945e75bd61082f19a8ad2ecc2dde887228 100644 --- a/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml @@ -43,7 +43,7 @@ services: container_name: sa-du-b200-gnb environment: USE_B2XX: 'yes' - USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14 + USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 18 --RUs.[0].att_tx 18 volumes: - ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf - /dev:/dev diff --git a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml index 2be92cdb38ae323339eac3e2c2ac53759d66e5bb..2ad0818a4777a0f1071a591fa63163c68d5d6378 100644 --- a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml @@ -26,7 +26,7 @@ services: container_name: sa-du-b200-gnb environment: USE_B2XX: 'yes' - USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14 + USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 18 --RUs.[0].att_tx 18 volumes: - ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf - /dev:/dev diff --git a/common/utils/websrv/DOC/websrv.md b/common/utils/websrv/DOC/websrv.md index 95a6676c4e1cdd812b9c96920e77f0a334db3623..55c3c891e8fe48bf2b089acbdc713798e21e5f23 100644 --- a/common/utils/websrv/DOC/websrv.md +++ b/common/utils/websrv/DOC/websrv.md @@ -1,7 +1,7 @@ -The oai web server is an optional monitoring and debugging tool. Purpose is to give access to oai softmodems functionalities via a web interface. In this first release interface to the telnet server commands and to the softscope are delivered. +The oai web server is an optional monitoring and debugging tool. Purpose is to give access to oai softmodems functionalities via a web interface. In this release interface to the telnet server commands and to the softscope are delivered. -* [Using the web server](webserverusage.md) -* [enhancing the webserver](webserverdevcmd.md) -* [web server architecture ](webserverarch.md) +* [Using the web server](websrvuse.md) +* [enhancing the webserver](websrvdev.md) +* [web server architecture ](websrvarch.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/websrv/DOC/websrvarch.md b/common/utils/websrv/DOC/websrvarch.md index f9701eec51dec350c8bace879e7d361eeeb889c7..963c53af7a276cad65faf3994737184ca03915cb 100644 --- a/common/utils/websrv/DOC/websrvarch.md +++ b/common/utils/websrv/DOC/websrvarch.md @@ -1,21 +1,24 @@ # web server interface principles -The web server interface is implemented in two parts: a back-end, included in the softmodem process and a front-end which is a browser application. +The web server interface is implemented in two parts: a back-end, included in the softmodem process and a front-end which is a browser application. -The oai web server back-end is implemented in a shared library to be loaded by the [oai shared library loader](loader) when `--websrv` option is specified on the command line. `libwebsrv.so ` code is common to all oai softmodem executables, the current release has been tested with the nr UE and the gNB. +The oai web server back-end is implemented in a shared library to be loaded by the [oai shared library loader](../../DOC/loader.md) when `--websrv` option is specified on the command line. `libwebsrv.so` code is common to all oai softmodem executables, + the current release has been tested with the nr UE and the gNB. The front-end is an [angular](https://angular.io/docs) application. After being built and installed it is delivered to browsers by the back-end at connection time. -Front-end and back-end communicate via http request - http response transactions, including `json` body. these `json` interfaces are defined in the [frontend/src/app/api/XXXX.api.ts](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/websrv/src/frontend/src/app/api/) files. Back-end decapsulates the http requests it receives, looking for the `json`body to determine the requested information or command. Then the back-end builds a http response, with a `json`body encapsulating the requested information or the requested command result. +Front-end and back-end communicate via http request - http response transactions, including `json` body. these `json` interfaces are defined in the [frontend/src/app/api/XXXX.api.ts](../frontend/src/app/api/) files. +Back-end uses a callback machanism to map received http requests to dedicated functions. Typically a callback function decapsulates the http requests it receives, looking for the `json`body to determine the requested information or command. Then the back-end builds a +http response, with a `json`body encapsulating the requested information or the requested command result. When unsolicited communication, from back-end to front-end is necessary, a [websocket](https://www.rfc-editor.org/rfc/rfc6455) link is opened. This is the case for the softscope interface. # web server interface source files -web server source files are located in [common/utils/websrv](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/websrv) +web server source files are located in [common/utils/websrv](..) 1. back-end files are directly located in the `websrv` repository -1. The [frontend/src](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/websrv/src/frontend) sub-directory contains the angular front-end source tree. -1. [common/utils/websrv/helpfiles](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/websrv/helpfiles) contains files delivered to the front-end to respond to help requests. +1. The [frontend/src](../frontend/src) sub-directory contains the angular front-end source tree. +1. [common/utils/websrv/helpfiles](../helpfiles) contains files delivered to the front-end to respond to help requests. -[oai web server interface home](websrv.md) \ No newline at end of file +[oai web server interface home](websrv.md) diff --git a/common/utils/websrv/DOC/websrvdev.md b/common/utils/websrv/DOC/websrvdev.md new file mode 100644 index 0000000000000000000000000000000000000000..317b97a3c36a8594d42a355b3f664563611bc410 --- /dev/null +++ b/common/utils/websrv/DOC/websrvdev.md @@ -0,0 +1,52 @@ +# enhancing the web server + +###### development platform + +Backend devlopment is classical C programming, using [libulfius](https://github.com/babelouest/ulfius/blob/master/API.md) for the web server implementation +and [libjansson](https://jansson.readthedocs.io/en/latest/) for formatting and accessing the JSON http bodies which are used by the angular frontend to exchange data with the server. +The backend processes the http requests coming from the frontend using the ulfius callback mechanism. backend can also send unsollicited data to the frontend using a websocket + +Frontend has been developped using the [angular framework](https://angular.io/) which implies TypeScript and HTML programming with the specificity of the node.js libraries and +angular extensions. + +Debugging the frontend side may be more difficult than the backend, some tools may help: +- Some IDE such as [vscode]( https://code.visualstudio.com/) are "angular aware" and can ease debugging your modifications . +- Setting UTIL log level to informational in the backend and websrv debug flag to 2 ( `--log_config.util_log_level info --websrv.debug 2` ) will trigger backend traces which may help, including the dump of JSON type http content +- Browser devloper tools such as console may also help + +There is a dedicated CMakeLists.txt, located in the websrv directory, to build both backend and frontend. Including the websrv option when configuring cmake ( `./build_oai --build-lib websrv` ) is required to be able to include the web server targets in the oai build scripts (either Makefile or ninja). + `libwebsrv.so` shared library is the backend binary. It is possibly dynamically loaded at runtime, which then triggers the execution of the +`websrv_autoinit` function that initializes the http server. Re-building the backend can be done using either `make websrv` or `ninja websrv` and it also re-builds the frontend . + +The frontend run-time is made of a set of files generated from the TypeScript, HTML, CSS sources via the npm utility. It also includes some directly edited files such as the helpfiles. Frontend run-time is installed in the `websrv` sub-directory of the build path +(usually `<oai repository>/cmake_targets/ran_build/build`) Re-building frontend can be done via the websrvfront target: `make websrvfront` or `ninja websrvfront`. + + +###### backend source files + +They are all located in the websrv repository +| source file |description | +|---|---| +| websrv.c | main backend file, starts the http server and contains functions for telnet server interface ( softmodem commands tab) | +| websrv.h | the only web server include file, contains utils prototypes, constants definitions, message definitions. Note that it must be kept consistent with frontend, unfortunatly we have not found a way to have common include files between C and javascript | +| websrv_utils.c | utility functions common to all backend sources: dump http request and JSON content. format string response from a file, a C string, a buffer asynchronously loaded. format help from help file | +| websrv_websockets.c | contains functions for the softscope interface (scope tab): initialize, close websocket, dispatch incoming messages, send a websocket message to frontend | +| websrv_scope.c | softscope specific functions: callbacks to process softope frontend request and function to send, receive and process softscope websocket messages | +| websrv_noforms.c websrv_noforms.h | stub functions to help using a common softscope interface for xforms softscope and the webserver softscope, could be removed when improving softscope architecture (don't use interface specific function in nr_physcope.c) | + + +###### main frontend source files + +Frontend directory tree comes from the angular framework. The root of this tree is `websrv/frontend/`. Main sub directories or files are: + +- `src/app/api` contains TypeScript files with functions to send http requests to the backend. These functions are used from components sources. +- `src/app/components/<component name>` contains the code (TypeScript, HTML and possibly CSS or XCSS) for a web page, for example the softscope, or popup page used to ask a question or return transaction status. +- `src/app/components/controls` contains TypeScript code used for managing some form fields used in the `softmodem commands` tab. +- `src/app/components/services` contain TypeScript code for utilities such as managing the websocket interface with the backend or downloading a file. +- `src/app/app-routing-module.ts` defines mapping between urls as entered by user and components +- `src/app/app.component.ts` `src/app/app.component.html` define the first page displayed to user +- `src/environments` contains environment.<build type>.ts file wich defines the `environment` variable depending on the build type. The delivered build scripts are using the `prod` version which has been written to make frontend and backend to interact properly in a production platform. Other build type is to be used in debug environment where frontend is not downloaded from the backend. +- `src/commondefs.ts`: constant definitions common to several TypeScript sources + + +[oai web serverinterface home](websrv.md) diff --git a/common/utils/websrv/DOC/websrvuse.md b/common/utils/websrv/DOC/websrvuse.md index eaaf863892a3f8ef41d5fc1e493a0875ae3d7492..2177820f8c5298e08ba2723e9014243530eb7c3e 100644 --- a/common/utils/websrv/DOC/websrvuse.md +++ b/common/utils/websrv/DOC/websrvuse.md @@ -1,102 +1,299 @@ -back-end and front-end are both built when the build of the `websrv` optional library is requested. When cmake configuration has been completed, with websrv enabled,font-end and back-end can be built separatly, using respectively `make frontend` or `make websrv` from the build repository. +## building the webserver -When all dependencies are met, you can build the web server interface components using the build_oai script with the `--build-lib all` option . As the web interface is an optional component, if it's dependencies are not found it won't stop the build. Web interface components (back-end or front-end) which cannot be built are just skipped. If you specifically ask for the webserver build ( `--build-lib websrv`) the build will fail if dependencies check failed. -###### build example when missing dependencies +back-end (the http server) and front-end (the html and javascript code for the browsers) are both built when the build of the `websrv` optional library is requested. +You can include the web server interface components in your build using the build_oai script with the `--build-lib "telnetsrv websrv"` option. +The related cmake cache entry in `ran_build/build/CMakeCache.txt` for building the web server +is `ENABLE_WEBSRV:BOOL=ON` + +When cmake configuration has been completed, with websrv enabled and all dependencies met,font-end and back-end +can be built separately, using respectively `make websrvfront` or `make websrv` from the build repository (replace make by ninja if you +build using ninja). + + + +###### build example when back-end dependency is not installed + +``` + ./build_oai --gNB --nrUE -w USRP --build-lib "telnetsrv websrv nrscope" +Will compile gNB +Will compile NR UE +Enabling build of optional shared library telnetsrv +Enabling build of optional shared library websrv +Enabling build of optional shared library nrscope +OPENAIR_DIR = /usr/local/oai/develop_unmodified/openairinterface5g +Running "cmake -DOAI_USRP=ON -DENABLE_TELNETSRV=ON -DENABLE_WEBSRV=ON -DENABLE_NRSCOPE=ON ../../.." +-- The C compiler identification is GNU 11.4.0 +-- The CXX compiler identification is GNU 11.4.0 +-- Detecting C compiler ABI info +-- Detecting C compiler ABI info - done +-- Check for working C compiler: /usr/bin/cc - skipped +-- Detecting C compile features +-- Detecting C compile features - done +-- Detecting CXX compiler ABI info +-- Detecting CXX compiler ABI info - done +-- Check for working CXX compiler: /usr/bin/c++ - skipped +-- Detecting CXX compile features +-- Detecting CXX compile features - done +-- Ccache not found. Consider installing it for faster compilation. Command: sudo apt/dnf install ccache +-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2") +-- Check if /opt/asn1c/bin/asn1c supports -gen-APER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-UPER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-JER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-BER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-OER +-- CMAKE_BUILD_TYPE is RelWithDebInfo +-- CPUARCH x86_64 +-- AVX512 intrinsics are OFF +-- AVX2 intrinsics are ON +-- Found Git: /usr/bin/git (found version "2.34.1") +-- Checking for module 'libconfig' +-- Found libconfig, version 1.5 +-- Checking for module 'openssl' +-- Found openssl, version 3.0.2 +-- Checking for module 'blas' +-- Found blas, version 3.10.3 +-- Checking for module 'lapacke' +-- Found lapacke, version 3.10.0 +-- Checking for module 'cblas' +-- No package 'cblas' found +-- Add enb specific telnet functions in libtelnetsrv_enb.so +-- No specific telnet functions for gnb +-- No specific telnet functions for 4Gue +-- Add 5Gue specific telnet functions in libtelnetsrv_5Gue.so +-- Add CI specific telnet functions in libtelnetsrv_ci.so +CMake Error at common/utils/websrv/CMakeLists.txt:31 (find_library): + Could not find ULFIUS using the following names: libulfius.so +-- Configuring incomplete, errors occurred! +See also "/usr/local/oai/develop_unmodified/openairinterface5g/cmake_targets/ran_build/build/CMakeFiles/CMakeOutput.log". +build have failed +``` +You can fix this first dependency problem, the backend dependency, by installing the libulfius library: + +On ubuntu: `sudo apt-get install libulfius-dev`, for fedora: `dnf install libulfius`. Some distribution don't have +libulfius package, instruction to install it can be found [here](https://github.com/babelouest/ulfius/blob/master/INSTALL.md) + +###### build example when front-end dependency is not installed ``` -./build_oai --build-lib all -Enabling build of all optional shared libraries (telnetsrv enbscope uescope nrscope websrv websrvfront) -RF HW set to None -OPENAIR_DIR = /usr/local/oai/websrv3/openairinterface5g -FreeDiameter prefix not found, install freeDiameter if EPC, HSS -running cmake -DENABLE_WEBSRV=ON -DENABLE_TELNETSRV=ON ../../.. -NETTLE VERSION_INSTALLED = 3.5.1 -NETTLE_VERSION_MAJOR = 3 -NETTLE_VERSION_MINOR = 5 -cuda include /usr/include -cuda library +./build_oai --build-lib "websrv telnetsrv nrscope" + + + + ./build_oai --gNB --nrUE -w USRP --build-lib "telnetsrv websrv nrscope" +Will compile gNB +Will compile NR UE +Enabling build of optional shared library telnetsrv +Enabling build of optional shared library websrv +Enabling build of optional shared library nrscope +OPENAIR_DIR = /usr/local/oai/develop_unmodified/openairinterface5g +Running "cmake -DOAI_USRP=ON -DENABLE_TELNETSRV=ON -DENABLE_WEBSRV=ON -DENABLE_NRSCOPE=ON ../../.." +-- Ccache not found. Consider installing it for faster compilation. Command: sudo apt/dnf install ccache +-- Check if /opt/asn1c/bin/asn1c supports -gen-APER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-UPER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-JER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-BER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-OER -- CMAKE_BUILD_TYPE is RelWithDebInfo -- CPUARCH x86_64 -- AVX512 intrinsics are OFF -- AVX2 intrinsics are ON --- No T1 Offload support detected -gcc -Wall -I. -I.. -I../itti -I../../../openair2/COMMON -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread -./_check_vcd || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false) -rm -f ./_check_vcd +-- Checking for module 'cblas' +-- No package 'cblas' found -- Add enb specific telnet functions in libtelnetsrv_enb.so -- No specific telnet functions for gnb -- No specific telnet functions for 4Gue -- Add 5Gue specific telnet functions in libtelnetsrv_5Gue.so -CMake Error at common/utils/websrv/CMakeLists.txt:3 (message): - ulfius library (https://github.com/babelouest/ulfius) not found, install - libulfius-dev (ubuntu) if you need to build websrv back-end +-- Add CI specific telnet functions in libtelnetsrv_ci.so +-- found libulfius for websrv +-- found libjansson for websrv +CMake Error at common/utils/websrv/CMakeLists.txt:45 (find_program): + Could not find NPM using the following names: npm -- Configuring incomplete, errors occurred! -See also "/usr/local/oai/websrv3/openairinterface5g/cmake_targets/ran_build/build/CMakeFiles/CMakeOutput.log". -See also "/usr/local/oai/websrv3/openairinterface5g/cmake_targets/ran_build/build/CMakeFiles/CMakeError.log". +See also "/usr/local/oai/develop_unmodified/openairinterface5g/cmake_targets/ran_build/build/CMakeFiles/CMakeOutput.log". build have failed ``` +Currently the web server frontend can run with nodejs 18, you can check the version (if any) installed on your system entering the `node -v` command. -###### build example (build-lib all) when dependencies are met -``` - ./build_oai --build-lib all -Enabling build of all optional shared libraries (telnetsrv enbscope uescope nrscope websrv websrvfront) -RF HW set to None -OPENAIR_DIR = /usr/local/oai/websrv3/openairinterface5g -FreeDiameter prefix not found, install freeDiameter if EPC, HSS -running cmake -DENABLE_WEBSRV=ON -DENABLE_TELNETSRV=ON ../../.. -NETTLE VERSION_INSTALLED = 3.5.1 -NETTLE_VERSION_MAJOR = 3 -NETTLE_VERSION_MINOR = 5 -cuda include /usr/include -cuda library +To prevent difficult situations with nodejs or npm versions it is better to specifically install the required nodejs version (after removing existing versions of npm and nodejs), as explained +[here](https://www.stewright.me/2023/04/install-nodejs-18-on-ubuntu-22-04/) for ubuntu. Similar instructions can be found for other distributions. +It is also possible to make several nodejs versions co-habiting on your system, this is beyond this doc. + + + ###### example: installing nodejs 18 on ubuntu +``` + +curl -s https://deb.nodesource.com/setup_18.x | sudo bash + +## Installing the NodeSource Node.js 18.x repo... + + +## Populating apt-get cache... + ++ apt-get update +Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB] +Hit:2 http://us.archive.ubuntu.com/ubuntu jammy InRelease +Get:3 http://security.ubuntu.com/ubuntu jammy-security/main i386 Packages [305 kB] +Get:4 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [678 kB] +Get:5 http://us.archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB] +Get:6 http://security.ubuntu.com/ubuntu jammy-security/main amd64 DEP-11 Metadata [42.8 kB] +Get:7 http://security.ubuntu.com/ubuntu jammy-security/main amd64 c-n-f Metadata [11.2 kB] +Get:8 http://security.ubuntu.com/ubuntu jammy-security/universe i386 Packages [553 kB] +Get:9 http://us.archive.ubuntu.com/ubuntu jammy-backports InRelease [109 kB] +Get:10 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 Packages [770 kB] +Get:11 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 DEP-11 Metadata [39.8 kB] +Get:12 http://us.archive.ubuntu.com/ubuntu jammy-updates/main i386 Packages [471 kB] +Get:13 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [892 kB] +Get:14 http://us.archive.ubuntu.com/ubuntu jammy-updates/main Translation-en [214 kB] +Get:15 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 DEP-11 Metadata [100 kB] +Get:16 http://us.archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [714 kB] +Get:17 http://us.archive.ubuntu.com/ubuntu jammy-updates/restricted Translation-en [114 kB] +Get:18 http://us.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [968 kB] +Get:19 http://us.archive.ubuntu.com/ubuntu jammy-updates/universe i386 Packages [648 kB] +Get:20 http://us.archive.ubuntu.com/ubuntu jammy-updates/universe Translation-en [211 kB] +Get:21 http://us.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 DEP-11 Metadata [288 kB] +Get:22 http://us.archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 DEP-11 Metadata [940 B] +Get:23 http://us.archive.ubuntu.com/ubuntu jammy-backports/main amd64 DEP-11 Metadata [4,924 B] +Get:24 http://us.archive.ubuntu.com/ubuntu jammy-backports/universe amd64 DEP-11 Metadata [15.6 kB] +Fetched 7,379 kB in 4s (2,095 kB/s) +Reading package lists... Done + +## Confirming "jammy" is supported... + ++ curl -sLf -o /dev/null 'https://deb.nodesource.com/node_18.x/dists/jammy/Release' + +## Adding the NodeSource signing key to your keyring... + ++ curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | gpg --dearmor | tee /usr/share/keyrings/nodesource.gpg >/dev/null + +## Creating apt sources list file for the NodeSource Node.js 18.x repo... + ++ echo 'deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x jammy main' > /etc/apt/sources.list.d/nodesource.list ++ echo 'deb-src [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x jammy main' >> /etc/apt/sources.list.d/nodesource.list + +## Running `apt-get update` for you... + ++ apt-get update +Hit:1 http://security.ubuntu.com/ubuntu jammy-security InRelease +Get:2 https://deb.nodesource.com/node_18.x jammy InRelease [4,563 B] +Get:3 https://deb.nodesource.com/node_18.x jammy/main amd64 Packages [776 B] +Hit:4 http://us.archive.ubuntu.com/ubuntu jammy InRelease +Hit:5 http://us.archive.ubuntu.com/ubuntu jammy-updates InRelease +Hit:6 http://us.archive.ubuntu.com/ubuntu jammy-backports InRelease +Fetched 5,339 B in 1s (7,666 B/s) +Reading package lists... Done + +## Run `sudo apt-get install -y nodejs` to install Node.js 18.x and npm +## You may also need development tools to build native addons: + sudo apt-get install gcc g++ make +## To install the Yarn package manager, run: + curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null + echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list + sudo apt-get update && sudo apt-get install yarn + + +sudo apt install nodejs -y +Reading package lists... Done +Building dependency tree... Done +Reading state information... Done +The following packages were automatically installed and are no longer required: + diodon libdiodon0 libxdo3 xdotool +Use 'sudo apt autoremove' to remove them. +The following NEW packages will be installed: + nodejs +0 upgraded, 1 newly installed, 0 to remove and 8 not upgraded. +Need to get 28.9 MB of archives. +After this operation, 188 MB of additional disk space will be used. +Get:1 https://deb.nodesource.com/node_18.x jammy/main amd64 nodejs amd64 18.17.1-deb-1nodesource1 [28.9 MB] +Fetched 28.9 MB in 3s (11.3 MB/s) +Selecting previously unselected package nodejs. +(Reading database ... 399541 files and directories currently installed.) +Preparing to unpack .../nodejs_18.17.1-deb-1nodesource1_amd64.deb ... +Unpacking nodejs (18.17.1-deb-1nodesource1) ... +Setting up nodejs (18.17.1-deb-1nodesource1) ... +Processing triggers for man-db (2.10.2-1) ... + + +``` + +###### build example when dependencies are met + + +``` bash + +./build_oai --ninja -c -C --gNB --nrUE -w USRP --build-lib "telnetsrv websrv nrscope" +Will compile gNB +Will compile NR UE +Enabling build of optional shared library telnetsrv +Enabling build of optional shared library websrv +Enabling build of optional shared library nrscope +OPENAIR_DIR = /usr/local/oai/develop_unmodified/openairinterface5g +Erased all previously producted files +Running "cmake -GNinja -DOAI_USRP=ON -DENABLE_TELNETSRV=ON -DENABLE_WEBSRV=ON -DENABLE_NRSCOPE=ON ../../.." +-- The C compiler identification is GNU 11.4.0 +-- The CXX compiler identification is GNU 11.4.0 +-- Detecting C compiler ABI info +-- Detecting C compiler ABI info - done +-- Check for working C compiler: /usr/bin/cc - skipped +-- Detecting C compile features +-- Detecting C compile features - done +-- Detecting CXX compiler ABI info +-- Detecting CXX compiler ABI info - done +-- Check for working CXX compiler: /usr/bin/c++ - skipped +-- Detecting CXX compile features +-- Detecting CXX compile features - done +-- Ccache not found. Consider installing it for faster compilation. Command: sudo apt/dnf install ccache +-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2") +-- Check if /opt/asn1c/bin/asn1c supports -gen-APER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-UPER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-JER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-BER +-- Check if /opt/asn1c/bin/asn1c supports -no-gen-OER -- CMAKE_BUILD_TYPE is RelWithDebInfo -- CPUARCH x86_64 -- AVX512 intrinsics are OFF -- AVX2 intrinsics are ON --- No T1 Offload support detected -gcc -Wall -I. -I.. -I../itti -I../../../openair2/COMMON -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread -./_check_vcd || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false) -rm -f ./_check_vcd +-- Found Git: /usr/bin/git (found version "2.34.1") +-- Checking for module 'libconfig' +-- Found libconfig, version 1.5 +-- Checking for module 'openssl' +-- Found openssl, version 3.0.2 +-- Checking for module 'blas' +-- Found blas, version 3.10.3 +-- Checking for module 'lapacke' +-- Found lapacke, version 3.10.0 +-- Checking for module 'cblas' +-- No package 'cblas' found -- Add enb specific telnet functions in libtelnetsrv_enb.so -- No specific telnet functions for gnb -- No specific telnet functions for 4Gue -- Add 5Gue specific telnet functions in libtelnetsrv_5Gue.so +-- Add CI specific telnet functions in libtelnetsrv_ci.so -- found libulfius for websrv -- found libjansson for websrv -- found npm for websrv -- Configuring webserver backend -- Configuring webserver frontend -- No Doxygen documentation requested +-- libforms library, required for scopes, found at /usr/lib/libforms.so +-- Found UHD: /usr/lib/x86_64-linux-gnu/libuhd.so -- Configuring done -- Generating done --- Build files have been written to: /usr/local/oai/websrv3/openairinterface5g/cmake_targets/ran_build/build -Log file for compilation is being written to: /usr/local/oai/websrv3/openairinterface5g/cmake_targets/log/telnetsrv.txt -telnetsrv compiled -Log file for compilation is being written to: /usr/local/oai/websrv3/openairinterface5g/cmake_targets/log/enbscope.txt -enbscope compiled -Log file for compilation is being written to: /usr/local/oai/websrv3/openairinterface5g/cmake_targets/log/uescope.txt -uescope compiled -Log file for compilation is being written to: /usr/local/oai/websrv3/openairinterface5g/cmake_targets/log/nrscope.txt -nrscope compiled -Log file for compilation is being written to: /usr/local/oai/websrv3/openairinterface5g/cmake_targets/log/websrv.txt -websrv compiled -Log file for compilation is being written to: /usr/local/oai/websrv3/openairinterface5g/cmake_targets/log/websrvfront.txt -websrvfront compiled -BUILD SHOULD BE SUCCESSFUL -``` - -# building and installing the front-end after cmake has been configured +-- Build files have been written to: /usr/local/oai/develop_unmodified/openairinterface5g/cmake_targets/ran_build/build +cd /usr/local/oai/develop_unmodified/openairinterface5g/cmake_targets/ran_build/build +Running "cmake --build . --target nr-softmodem nr-cuup nr-uesoftmodem oai_usrpdevif telnetsrv websrv nrscope params_libconfig coding rfsimulator dfts -- -j8" +Log file for compilation is being written to: /usr/local/oai/develop_unmodified/openairinterface5g/cmake_targets/log/all.txt +nr-softmodem nr-cuup nr-uesoftmodem oai_usrpdevif telnetsrv websrv nrscope params_libconfig coding rfsimulator dfts compiled +BUILD SHOULD BE SUCCESSFUL -Before building the front-end you need to install the npm node.js installer, otherwise the make target won't exist: +``` -`apt-get install npm` for ubuntu or `dnf install npm`for fedora +###### building and installing the front-end after cmake has been successfully configured -then configure cmake to be able to build and install the frontend without using the build_oai script: -``` bash +``` cd \<oai repository\>/openairinterface5g/cmake_targets/ran_build/build make websrvfront up to date, audited 1099 packages in 3s @@ -135,29 +332,21 @@ Built target websrvfront ``` - -# Building and installing the web server back-end after cmake has been configured - -The back-end has two dependencies: - -1. the [ulfius library](https://github.com/babelouest/ulfius) and the corresponding include files which are provided by the ubuntu libulfius-dev package: `sudo apt-get install -y libulfius-dev` -2. the [jansson](https://github.com/akheron/jansson-debian) library and the corresponding include files which are provided by the ubuntu libjansson-dev package: `sudo apt-get install -y libjansson-dev` - -Dependencies can also be installed on fedora distribution, the jansson package is `jansson-devel`, ulfius has to be installed as explained [here](https://github.com/babelouest/ulfius/blob/master/INSTALL.md#pre-compiled-packages). - -The websrv targets won't be available till cmake has been successfully configured with the websrv option enabled +###### building and installing the back-end after cmake has been successfully configured ```bash - cd \<oai repository\>/openairinterface5g + cd <oai repository>/openairinterface5g source oaienv cd cmake_targets ./build_oai --build-lib websrv ``` or, without the help of the `build_oai` script: + ```bash cd \<oai repository\>/openairinterface5g/cmake_targets/ran_build/build make websrv ``` + This will create the `libwebsrv.so` file in the `targets/bin` and `cmake_targets/ran_build/build` sub directories of the oai repository. When starting the softmodem, you must specify the **_\-\-websrv_** option to load and start the web server. The web server is loaded via the [oai shared library loader](loader). @@ -166,7 +355,7 @@ When starting the softmodem, you must specify the **_\-\-websrv_** option to loa ## web server parameters -The web server back-end is using the [oai configuration module](Config/Rtusage). web server parameters must be specified in the websrv section. +The web server back-end is using the [oai configuration module](Config/Rtusage). web server parameters must be specified in the websrv section. | name | type | default | description | |:---:|:---:|:---:|:----| @@ -180,7 +369,7 @@ The web server back-end is using the [oai configuration module](Config/Rtusage). ## running the back-end To trigger the back-end use the `--websrv` option, possibly modifying the parameters as explained in the previous chapter. The two following commands allow starting the oai gNB and the oai 5G UE on the same computer, starting the telnet server and the web interface on both executables. -`./nr-softmodem -O /usr/local/oai/conf/gnb.band78.sa.fr1.106PRB.usrpb210.conf --rfsim --rfsimulator.serveraddr server --telnetsrv --telnetsrv.listenstdin --websrv --rfsimulator.options chanmod` +`./nr-softmodem -O /usr/local/oai/conf/gnb.band78.sa.fr1.106PRB.usrpb210.conf --rfsim --rfsimulator.serveraddr server --telnetsrv --telnetsrv.listenstdin --websrv --rfsimulator.options chanmod` .`/nr-uesoftmodem -O /usr/local/oai/conf/nrue_sim.conf --sa --numerology 1 -r 106 -C 3649440000 --rfsim --rfsimulator.serveraddr 127.0.0.1 --websrv --telnetsrv --websrv.listenport 8092 --telnetsrv.listenport 8091` @@ -191,18 +380,20 @@ To trigger the back-end use the `--websrv` option, possibly modifying the parame Assuming that the previous commands run successfully and that you also run your browser on the same host, you should be able to connect to the gNB and UE web interface using respectively the following url's: http://127.0.0.1:8090/websrv/index.html + http://127.0.0.1:8092/websrv/index.html The interface should be intuitive enough, keeping in mind the following restrictions: - The command tab is not available if the telnet server is not enabled -- The softscope tab is not available if the xforms scope is started `(-d` option) +- The softscope tab is not available if the xforms scope is started (`-d` option) - Only one connection is supported to a back-end, especially for the scope interface Some front-end objects, which usage are less intuitive provide a tooltip to help interface usage. ## some webserver screenshots - - - +- [main page](main.png) +- [Configuring logs](logscfg.png) +- [scope interface](scope.png) + [oai web serverinterface home](websrv.md) diff --git a/doc/NR_SA_Tutorial_COTS_UE.md b/doc/NR_SA_Tutorial_COTS_UE.md index 25997f8f8859a66a32a3337c3e6ca4f5d4fbc1a6..13b07df327834f1a4f3bb3c5fe698a8c3712e2ec 100644 --- a/doc/NR_SA_Tutorial_COTS_UE.md +++ b/doc/NR_SA_Tutorial_COTS_UE.md @@ -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.2-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.3-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 32 GB - Laptop for UE @@ -45,7 +45,7 @@ Please install and configure OAI CN5G as described here: ## 2.2 SIM Card -Program SIM Card with [Open Cells Project](https://open-cells.com/) application [uicc-v2.6](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v2.6.tgz). +Program SIM Card with [Open Cells Project](https://open-cells.com/) application [uicc-v3.2](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v3.2.tgz). ```bash sudo ./program_uicc --adm 12345678 --imsi 001010000000001 --isdn 00000001 --acc 0001 --key fec86ba6eb707ed08905757b1bb44b8f --opc C42449363BBAD02B66D16BC975D77CC1 -spn "OpenAirInterface" --authenticate diff --git a/doc/NR_SA_Tutorial_OAI_CN5G.md b/doc/NR_SA_Tutorial_OAI_CN5G.md index 5e6ad3fdbb936bd63e13a82ebb614e5ca104ad1d..9f17d944552f0f6b59164c493e6adb45ac797797 100644 --- a/doc/NR_SA_Tutorial_OAI_CN5G.md +++ b/doc/NR_SA_Tutorial_OAI_CN5G.md @@ -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.2-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.3-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 32 GB diff --git a/doc/NR_SA_Tutorial_OAI_nrUE.md b/doc/NR_SA_Tutorial_OAI_nrUE.md index 81c861bdfa4e29650724908b01c5de142ca42d4f..8091d44e743ef859dad4f575d6e00973b8292b2c 100644 --- a/doc/NR_SA_Tutorial_OAI_nrUE.md +++ b/doc/NR_SA_Tutorial_OAI_nrUE.md @@ -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.2-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.3-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.2-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.3-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/) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 8d0f6418e2dcd21c6141c4d09ec842afab785ff1..64653a280b820d5dc99cc04a931efdd721338d64 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -465,6 +465,10 @@ static void UE_synch(void *arg) { } else { UE->is_synchronized = 1; } + if (UE->synch_request.received_synch_request == 1) { + UE->is_synchronized = 0; + UE->synch_request.received_synch_request = 0; + } } else { if (UE->UE_scan_carrier == 1) { diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 310b2f0e7501898a98380994d95cc296549603df..7396b2af8f13d982e0700d944e5d80e1278335be 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -121,10 +121,7 @@ void nr_modulation(uint32_t *in, uint8_t* in_bytes = (uint8_t*) in; uint64_t* in64 = (uint64_t*) in; int64_t* out64 = (int64_t*) out; - uint8_t idx; - uint32_t i,j; - uint32_t bit_cnt; - uint64_t x,x1,x2; + uint32_t i; #if defined(__SSE2__) __m128i *nr_mod_table128; @@ -145,7 +142,7 @@ void nr_modulation(uint32_t *in, i = i*8/2; nr_mod_table32 = (int32_t*) nr_qpsk_mod_table; while (i<length/2) { - idx = ((in_bytes[(i*2)/8]>>((i*2)&0x7)) & mask); + const int idx = ((in_bytes[(i * 2) / 8] >> ((i * 2) & 0x7)) & mask); out32[i] = nr_mod_table32[idx]; i++; } @@ -154,7 +151,7 @@ void nr_modulation(uint32_t *in, case 2: nr_mod_table32 = (int32_t*) nr_qpsk_mod_table; for (i=0; i<length/mod_order; i++) { - idx = ((in[i*2/32]>>((i*2)&0x1f)) & mask); + const int idx = ((in[i * 2 / 32] >> ((i * 2) & 0x1f)) & mask); out32[i] = nr_mod_table32[idx]; } return; @@ -167,66 +164,68 @@ void nr_modulation(uint32_t *in, // the bits that are left out i = i*8/4; while (i<length/4) { - idx = ((in_bytes[(i*4)/8]>>((i*4)&0x7)) & mask); + const int idx = ((in_bytes[(i * 4) / 8] >> ((i * 4) & 0x7)) & mask); out32[i] = nr_16qam_mod_table[idx]; i++; } return; case 6: - j = 0; - for (i=0; i<length/192; i++) { - x = in64[i*3]; - x1 = x&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x>>12)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x>>24)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x>>36)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x>>48)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x2 = (x>>60); - x = in64[i*3+1]; + for (i = 0; i < length - 3 * 64; i += 3 * 64) { + uint64_t x = *in64++; + uint64_t x1 = x & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x >> 12) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x >> 24) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x >> 36) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x >> 48) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + uint64_t x2 = (x >> 60); + x = *in64++; x2 |= x<<4; - x1 = x2&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x2>>12)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x2>>24)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x2>>36)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x2>>48)&4095; - out64[j++] = nr_64qam_mod_table[x1]; + x1 = x2 & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x2 >> 12) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x2 >> 24) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x2 >> 36) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x2 >> 48) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; x2 = ((x>>56)&0xf0) | (x2>>60); - x = in64[i*3+2]; + x = *in64++; x2 |= x<<8; - x1 = x2&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x2>>12)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x2>>24)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x2>>36)&4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x2>>48)&4095; - out64[j++] = nr_64qam_mod_table[x1]; + x1 = x2 & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x2 >> 12) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x2 >> 24) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x2 >> 36) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (x2 >> 48) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; x2 = ((x>>52)&0xff0) | (x2>>60); - out64[j++] = nr_64qam_mod_table[x2]; + *out64++ = nr_64qam_mod_table[x2]; } - i *= 24; - bit_cnt = i * 8; - while (bit_cnt < length) { - uint32_t xx; - memcpy(&xx, in_bytes+i, sizeof(xx)); - x1 = xx & 4095; - out64[j++] = nr_64qam_mod_table[x1]; - x1 = (xx >> 12) & 4095; - out64[j++] = nr_64qam_mod_table[x1]; - i += 3; - bit_cnt += 24; + while (i + 24 <= length) { + uint32_t xx = 0; + memcpy(&xx, in_bytes + i / 8, 3); + uint64_t x1 = xx & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + x1 = (xx >> 12) & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; + i += 24; + } + if (i != length) { + uint32_t xx = 0; + memcpy(&xx, in_bytes + i / 8, 2); + uint64_t x1 = xx & 0xfff; + *out64++ = nr_64qam_mod_table[x1]; } return; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 0d4806f74e9eee571baad15ba93c6a959d6d9735..7f8bfb82981af8a382043dcb2e98374bbe85e1b1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -184,8 +184,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// uint32_t available_bits = G; - uint32_t scrambled_output[(available_bits>>5)+1]; - memset(scrambled_output, 0, ((available_bits>>5)+1)*sizeof(uint32_t)); + // +1 because size can be not modulo 4 + uint32_t scrambled_output[available_bits / (8 * sizeof(uint32_t)) + 1]; + memset(scrambled_output, 0, sizeof(scrambled_output)); nr_pusch_codeword_scrambling(harq_process_ul_ue->f, available_bits, diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 7c67b22756d8f7460551b8185b58e4b901ff0378..08f552d9d3d7114c9575cce47d6220a1a6030f75 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -40,6 +40,7 @@ MESSAGE_DEF(F1AP_UL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_ul_r MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_req_t, f1ap_ue_context_release_req) MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cmd) MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_complete_t, f1ap_ue_context_release_complete) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQUIRED, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_required_t, f1ap_ue_context_modification_required) /* RRC -> F1AP messages */ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t , f1ap_dl_rrc_message ) @@ -48,6 +49,8 @@ MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_se MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp) MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_req_t, f1ap_ue_context_modification_req) MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_resp_t, f1ap_ue_context_modification_resp) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_CONFIRM, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_confirm_t, f1ap_ue_context_modification_confirm) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REFUSE, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_refuse_t, f1ap_ue_context_modification_refuse) /* CU -> DU*/ MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 3d594a695eeeaf9c25a546475576c5bd0e9c61de..2f95ee8cdc53e842b5ee5bf51fa624d4cf56cec7 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -44,6 +44,9 @@ #define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req #define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp #define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail +#define F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_required +#define F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_confirm +#define F1AP_UE_CONTEXT_MODIFICATION_REFUSE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_refuse #define F1AP_DL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_dl_rrc_message #define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req @@ -417,6 +420,28 @@ typedef enum F1ap_Cause_e { F1AP_CAUSE_MISC, } f1ap_Cause_t; +typedef struct f1ap_ue_context_modif_required_t { + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; + du_to_cu_rrc_information_t *du_to_cu_rrc_information; + f1ap_Cause_t cause; + long cause_value; +} f1ap_ue_context_modif_required_t; + +typedef struct f1ap_ue_context_modif_confirm_t { + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; + uint8_t *rrc_container; + int rrc_container_length; +} f1ap_ue_context_modif_confirm_t; + +typedef struct f1ap_ue_context_modif_refuse_t { + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; + f1ap_Cause_t cause; + long cause_value; +} f1ap_ue_context_modif_refuse_t; + typedef struct f1ap_ue_context_release_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 7cc23e88fa3dbf75da72850ffba18e5771836fc7..617366563c4d3a955dd3bf125fd765dc575cfd94 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -184,6 +184,16 @@ void *F1AP_CU_task(void *arg) { &F1AP_PAGING_IND(received_msg)); break; + case F1AP_UE_CONTEXT_MODIFICATION_CONFIRM: + CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(received_msg)); + break; + + case F1AP_UE_CONTEXT_MODIFICATION_REFUSE: + CU_send_UE_CONTEXT_MODIFICATION_REFUSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(received_msg)); + break; + // case F1AP_SETUP_RESPONSE: // This is from RRC // CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp) // break; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index a72a359c5b489a8b2f412b5bfe1a851c7b64edb0..4b91903d5fb0ec4f5cd7beb6dafe6da2929cbd06 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -1701,14 +1701,264 @@ int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, AssertFatal(1==0,"Not implemented yet\n"); } -int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) { - AssertFatal(1==0,"Not implemented yet\n"); +int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED); + f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p); + + F1AP_UEContextModificationRequired_t *container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequired; + F1AP_UEContextModificationRequiredIEs_t *ie = NULL; + + /* required: GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + required->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + + /* required: GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + required->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + + /* optional: Resource Coordination Transfer Container */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer, + false); + AssertFatal(ie == NULL, "handling of Resource Coordination Transfer Container not implemented\n"); + + /* optional: DU to CU RRC Information */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, + false); + if (ie != NULL) { + F1AP_DUtoCURRCInformation_t *du2cu = &ie->value.choice.DUtoCURRCInformation; + required->du_to_cu_rrc_information = malloc(sizeof(*required->du_to_cu_rrc_information)); + AssertFatal(required->du_to_cu_rrc_information != NULL, "memory allocation failed\n"); + + required->du_to_cu_rrc_information->cellGroupConfig = malloc(du2cu->cellGroupConfig.size); + AssertFatal(required->du_to_cu_rrc_information->cellGroupConfig != NULL, "memory allocation failed\n"); + memcpy(required->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig.buf, du2cu->cellGroupConfig.size); + required->du_to_cu_rrc_information->cellGroupConfig_length = du2cu->cellGroupConfig.size; + + AssertFatal(du2cu->measGapConfig == NULL, "handling of measGapConfig not implemented\n"); + AssertFatal(du2cu->requestedP_MaxFR1 == NULL, "handling of requestedP_MaxFR1 not implemented\n"); + } + + /* optional: DRB Required to Be Modified List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_DRBs_Required_ToBeModified_List, + false); + AssertFatal(ie == NULL, "handling of DRBs Required to be modified list not implemented\n"); + + /* optional: SRB Required to be Released List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_SRBs_Required_ToBeReleased_List, + false); + AssertFatal(ie == NULL, "handling of SRBs Required to be released list not implemented\n"); + + /* optional: DRB Required to be Released List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_DRBs_Required_ToBeReleased_List, + false); + AssertFatal(ie == NULL, "handling of DRBs Required to be released list not implemented\n"); + + /* mandatory: Cause */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true); + switch (ie->value.choice.Cause.present) { + case F1AP_Cause_PR_radioNetwork: + required->cause = F1AP_CAUSE_RADIO_NETWORK; + required->cause_value = ie->value.choice.Cause.choice.radioNetwork; + break; + case F1AP_Cause_PR_transport: + required->cause = F1AP_CAUSE_TRANSPORT; + required->cause_value = ie->value.choice.Cause.choice.transport; + break; + case F1AP_Cause_PR_protocol: + required->cause = F1AP_CAUSE_PROTOCOL; + required->cause_value = ie->value.choice.Cause.choice.protocol; + break; + case F1AP_Cause_PR_misc: + required->cause = F1AP_CAUSE_MISC; + required->cause_value = ie->value.choice.Cause.choice.misc; + break; + default: + LOG_W(F1AP, "Unknown cause for UE Context Modification required message\n"); + /* fall through */ + case F1AP_Cause_PR_NOTHING: + required->cause = F1AP_CAUSE_NOTHING; + break; + } + + /* optional: BH RLC Channel Required to be Released List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_BHChannels_Required_ToBeReleased_List, + false); + AssertFatal(ie == NULL, "handling of BH RLC Channel Required to be Released list not implemented\n"); + + /* optional: SL DRB Required to Be Modified List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_SLDRBs_Required_ToBeModified_List, + false); + AssertFatal(ie == NULL, "handling of SL DRB Required to be modified list not implemented\n"); + + /* optional: SL DRB Required to be Released List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_SLDRBs_Required_ToBeReleased_List, + false); + AssertFatal(ie == NULL, "handling of SL DRBs Required to be released list not implemented\n"); + + /* optional: Candidate Cells To Be Cancelled List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_Candidate_SpCell_List, + false); + AssertFatal(ie == NULL, "handling of candidate cells to be cancelled list not implemented\n"); + + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + return 0; } -int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, - F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t) { - AssertFatal(1==0,"Not implemented yet\n"); +int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm) +{ + F1AP_F1AP_PDU_t pdu = {0}; + pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, tmp); + tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModificationRequired; + tmp->criticality = F1AP_Criticality_reject; + tmp->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextModificationConfirm; + F1AP_UEContextModificationConfirm_t *out = &tmp->value.choice.UEContextModificationConfirm; + + /* mandatory: GNB_CU_UE_F1AP_ID */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationConfirmIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_UEContextModificationConfirmIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie1->value.choice.GNB_CU_UE_F1AP_ID = confirm->gNB_CU_ue_id; + + /* mandatory: GNB_DU_UE_F1AP_ID */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationConfirmIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_UEContextModificationConfirmIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie2->value.choice.GNB_DU_UE_F1AP_ID = confirm->gNB_DU_ue_id; + + /* optional: Resource Coordination Transfer Container */ + /* not implemented*/ + + /* optional: DRB Modified List */ + /* not implemented*/ + + /* optional: RRC Container */ + if (confirm->rrc_container != NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationConfirmIEs_t, ie); + ie->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationConfirmIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char *)confirm->rrc_container, confirm->rrc_container_length); + } + + /* optional: CriticalityDiagnostics */ + /* not implemented*/ + + /* optional: Execute Duplication */ + /* not implemented*/ + + /* optional: Resource Coordination Transfer Information */ + /* not implemented*/ + + /* optional: SL DRB Modified List */ + /* not implemented*/ + + /* encode */ + uint8_t *buffer = NULL; + uint32_t len = 0; + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 UE Context Modification Confirm\n"); + return -1; + } + f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0); + return 0; +} + +int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse) +{ + F1AP_F1AP_PDU_t pdu = {0}; + pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome; + asn1cCalloc(pdu.choice.unsuccessfulOutcome, tmp); + tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModificationRequired; + tmp->criticality = F1AP_Criticality_reject; + tmp->value.present = F1AP_UnsuccessfulOutcome__value_PR_UEContextModificationRefuse; + F1AP_UEContextModificationRefuse_t *out = &tmp->value.choice.UEContextModificationRefuse; + + /* mandatory: GNB_CU_UE_F1AP_ID */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRefuseIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_UEContextModificationRefuseIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie1->value.choice.GNB_CU_UE_F1AP_ID = refuse->gNB_CU_ue_id; + + /* mandatory: GNB_DU_UE_F1AP_ID */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRefuseIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_UEContextModificationRefuseIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie2->value.choice.GNB_DU_UE_F1AP_ID = refuse->gNB_DU_ue_id; + + /* optional: Cause */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRefuseIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_Cause; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_UEContextModificationRefuseIEs__value_PR_Cause; + F1AP_Cause_t *cause = &ie3->value.choice.Cause; + switch (refuse->cause) { + case F1AP_CAUSE_RADIO_NETWORK: + cause->present = F1AP_Cause_PR_radioNetwork; + cause->choice.radioNetwork = refuse->cause_value; + break; + case F1AP_CAUSE_TRANSPORT: + cause->present = F1AP_Cause_PR_transport; + cause->choice.transport = refuse->cause_value; + break; + case F1AP_CAUSE_PROTOCOL: + cause->present = F1AP_Cause_PR_protocol; + cause->choice.protocol = refuse->cause_value; + break; + case F1AP_CAUSE_MISC: + cause->present = F1AP_Cause_PR_misc; + cause->choice.misc = refuse->cause_value; + break; + case F1AP_CAUSE_NOTHING: + default: + cause->present = F1AP_Cause_PR_NOTHING; + break; + } // switch + + /* optional: CriticalityDiagnostics */ + /* not implemented*/ + + /* encode */ + uint8_t *buffer = NULL; + uint32_t len = 0; + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 UE Context Modification Refuse\n"); + return -1; + } + f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0); + return 0; } diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h index 32a54bc6ccbf05a7695c16cfc8e9b35bcd6cf1a1..76bbecb2b89176dcedfe3f82b6378aae26e44648 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.h +++ b/openair2/F1AP/f1ap_cu_ue_context_management.h @@ -85,12 +85,11 @@ int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, /* * UE Context Modification Required (gNB-DU initiated) */ -int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu); -int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, - F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t); +int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); + +int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm); + +int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse); /* * UE Inactivity Notification diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index a7af049c2ad13f6a4997a6a92090c91d1a1b4cd4..8f8258a1f82de311a178d0dd41dddd7fda778f0e 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -169,6 +169,10 @@ void *F1AP_DU_task(void *arg) { DU_send_UE_CONTEXT_RELEASE_COMPLETE(myInstance, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg)); break; + case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED: + DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg)); + break; + case TERMINATE_MESSAGE: LOG_W(F1AP, " *** Exiting F1AP thread\n"); itti_exit_task(); diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 2430b2f8700646167307f6f9b3e73f6180d0fb6c..352a29bd06e92c76687ba0553577c12ac2a1d18f 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -1285,12 +1285,252 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) { - AssertFatal(1==0,"Not implemented yet\n"); + +int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required) +{ + /* 0. Message Type */ + F1AP_F1AP_PDU_t pdu = {0}; + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu.choice.initiatingMessage, tmp); + tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModificationRequired; + tmp->criticality = F1AP_Criticality_reject; + tmp->value.present = F1AP_InitiatingMessage__value_PR_UEContextModificationRequired; + F1AP_UEContextModificationRequired_t *out = &tmp->value.choice.UEContextModificationRequired; + + /* mandatory GNB_CU_UE_F1AP_ID */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie1->value.choice.GNB_CU_UE_F1AP_ID = required->gNB_CU_ue_id; + + /* mandatory: GNB_DU_UE_F1AP_ID */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie2->value.choice.GNB_DU_UE_F1AP_ID = required->gNB_DU_ue_id; + + /* optional: Resource Coordination Transfer Container */ + /* not implemented!*/ + + /* optional: DU-to-CU RRC Container */ + if (required->du_to_cu_rrc_information) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_DUtoCURRCInformation; + + const du_to_cu_rrc_information_t *du2cu = required->du_to_cu_rrc_information; + AssertFatal(du2cu->cellGroupConfig != NULL, "du2cu cellGroupConfig is mandatory!\n"); + + /* mandatorycellGroupConfig */ + OCTET_STRING_fromBuf(&ie3->value.choice.DUtoCURRCInformation.cellGroupConfig, + (const char *)du2cu->cellGroupConfig, + du2cu->cellGroupConfig_length); + + /* optional: measGapConfig */ + if (du2cu->measGapConfig != NULL) { + OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.measGapConfig, + (const char *)du2cu->measGapConfig, + du2cu->measGapConfig_length); + } + + /* optional: requestedP_MaxFR1 */ + if (du2cu->requestedP_MaxFR1 != NULL) { + OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, + (const char *)du2cu->requestedP_MaxFR1, + du2cu->requestedP_MaxFR1_length); + } + } + + /* optional: DRB required to be modified */ + /* not implemented */ + + /* optional: SRB required to be released */ + /* not implemented */ + + /* optional: DRB required to be released */ + /* not implemented */ + + /* mandatory: cause */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_Cause; + ie4->criticality = F1AP_Criticality_reject; + ie4->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_Cause; + F1AP_Cause_t *cause = &ie4->value.choice.Cause; + switch (required->cause) { + case F1AP_CAUSE_RADIO_NETWORK: + cause->present = F1AP_Cause_PR_radioNetwork; + cause->choice.radioNetwork = required->cause_value; + break; + case F1AP_CAUSE_TRANSPORT: + cause->present = F1AP_Cause_PR_transport; + cause->choice.transport = required->cause_value; + break; + case F1AP_CAUSE_PROTOCOL: + cause->present = F1AP_Cause_PR_protocol; + cause->choice.protocol = required->cause_value; + break; + case F1AP_CAUSE_MISC: + cause->present = F1AP_Cause_PR_misc; + cause->choice.misc = required->cause_value; + break; + case F1AP_CAUSE_NOTHING: + default: + cause->present = F1AP_Cause_PR_NOTHING; + break; + } // switch + + /* optional: BH RLC Channel Required to be Released List */ + /* not implemented */ + + /* optional: SL DRB Required to Be Modified List */ + /* not implemented */ + + /* optional: SL DRB Required to be Released List */ + /* not implemented */ + + /* optional: Candidate Cells To Be Cancelled List */ + /* not implemented */ + + /* encode */ + uint8_t *buffer = NULL; + uint32_t len = 0; + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 context release request\n"); + return -1; + } + + f1ap_itti_send_sctp_data_req(false, instance, buffer, len, getCxt(false, instance)->default_sctp_stream_id); + return 0; } -int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) { - AssertFatal(1==0,"Not implemented yet\n"); + +int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +{ + F1AP_UEContextModificationConfirm_t *container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationConfirm; + f1ap_ue_context_modif_confirm_t confirm = {0}; + F1AP_UEContextModificationConfirmIEs_t *ie = NULL; + + /* mandatory: GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + confirm.gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + + /* mandatory: GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + confirm.gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + + /* optional: Resource Coordination Transfer Container */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer, + false); + AssertFatal(ie == NULL, "handling of Resource Coordination Transfer Container not implemented\n"); + + /* optional: DRBS Modified List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_DRBs_Modified_List, + false); + AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n"); + + /* optional: RRC Container */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, false); + if (ie != NULL) { + F1AP_RRCContainer_t *rrc_container = &ie->value.choice.RRCContainer; + confirm.rrc_container = malloc(rrc_container->size); + AssertFatal(confirm.rrc_container != NULL, "memory allocation failed\n"); + memcpy(confirm.rrc_container, rrc_container->buf, rrc_container->size); + confirm.rrc_container_length = rrc_container->size; + } + + /* optional: Criticality Diagnostics */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_CriticalityDiagnostics, + false); + AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n"); + + /* optional: Execute Duplication */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_ExecuteDuplication, + false); + AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n"); + + /* optional: Resource Coordination Transfer Information */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferInformation, + false); + AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n"); + + /* optional: SL DRB Modified List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_SLDRBs_Modified_List, + false); + AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n"); + + ue_context_modification_confirm(&confirm); + return 0; +} + +int DU_handle_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +{ + F1AP_UEContextModificationRefuse_t *container = &pdu->choice.unsuccessfulOutcome->value.choice.UEContextModificationRefuse; + f1ap_ue_context_modif_refuse_t refuse = {0}; + F1AP_UEContextModificationRefuseIEs_t *ie = NULL; + + /* mandatory: GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + refuse.gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + + /* mandatory: GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + refuse.gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + + /* mandatory: Cause */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true); + switch (ie->value.choice.Cause.present) { + case F1AP_Cause_PR_radioNetwork: + refuse.cause = F1AP_CAUSE_RADIO_NETWORK; + refuse.cause_value = ie->value.choice.Cause.choice.radioNetwork; + break; + case F1AP_Cause_PR_transport: + refuse.cause = F1AP_CAUSE_TRANSPORT; + refuse.cause_value = ie->value.choice.Cause.choice.transport; + break; + case F1AP_Cause_PR_protocol: + refuse.cause = F1AP_CAUSE_PROTOCOL; + refuse.cause_value = ie->value.choice.Cause.choice.protocol; + break; + case F1AP_Cause_PR_misc: + refuse.cause = F1AP_CAUSE_MISC; + refuse.cause_value = ie->value.choice.Cause.choice.misc; + break; + default: + LOG_W(F1AP, "Unknown cause for UE Context Modification Refuse message\n"); + /* fall through */ + case F1AP_Cause_PR_NOTHING: + refuse.cause = F1AP_CAUSE_NOTHING; + break; + } + + /* optional: Criticality Diagnostics */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, + ie, + container, + F1AP_ProtocolIE_ID_id_CriticalityDiagnostics, + false); + AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n"); + + ue_context_modification_refuse(&refuse); + return 0; } diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h index 51b8fa6dce12b776ce52610cff8488fc0c7a43de..cd8565f32800079b9ae6fa079a707c5f55f403ff 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.h +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -79,13 +79,11 @@ int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance); /* * UE Context Modification Required (gNB-DU initiated) */ -int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance); -int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu); +int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required); -int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *req); +int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); + +int DU_handle_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); /* * UE Inactivity Notification diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index 3eb4b1d86d1ae5680399f5e723582efb27685c1a..cf2530c8501247819eca89cf0c99cf3a8e3417f2 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -52,7 +52,7 @@ static const f1ap_message_processing_t f1ap_messages_processing[][3] = { {DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0}, /* UEContextSetup */ {DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0}, /* UEContextRelease */ {DU_handle_UE_CONTEXT_MODIFICATION_REQUEST, CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE, 0}, /* UEContextModification */ - {0, 0, 0}, /* UEContextModificationRequired */ + {CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED, DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM, DU_handle_UE_CONTEXT_MODIFICATION_REFUSE}, /* UEContextModificationRequired */ {0, 0, 0}, /* UEMobilityCommand */ {CU_handle_UE_CONTEXT_RELEASE_REQUEST, 0, 0}, /* UEContextReleaseRequest */ {CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER, 0, 0}, /* InitialULRRCMessageTransfer */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 0d9f2c2a51242f35953260454af5b10c027be378..4ed3d84a8f940eae6968923b95d31bc8dce26b28 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -4642,17 +4642,8 @@ int compute_pucch_crc_size(int O_uci) } } -uint16_t compute_pucch_prb_size(uint8_t format, - uint8_t nr_prbs, - uint16_t O_uci, - NR_PUCCH_MaxCodeRate_t *maxCodeRate, - uint8_t Qm, - uint8_t n_symb, - uint8_t n_re_ctrl) +float get_max_code_rate(NR_PUCCH_MaxCodeRate_t *maxCodeRate) { - int O_crc = compute_pucch_crc_size(O_uci); - int O_tot = O_uci + O_crc; - int rtimes100; switch(*maxCodeRate){ case NR_PUCCH_MaxCodeRate_zeroDot08 : @@ -4680,12 +4671,46 @@ uint16_t compute_pucch_prb_size(uint8_t format, AssertFatal(1==0,"Invalid MaxCodeRate"); } - float r = (float)rtimes100/100; + float r = (float)rtimes100 / 100; + return r; +} + +int get_f3_dmrs_symbols(NR_PUCCH_Resource_t *pucchres, NR_PUCCH_Config_t *pucch_Config) +{ + int f3_dmrs_symbols; + int add_dmrs_flag; + if (pucch_Config->format3 == NULL) + add_dmrs_flag = 0; + else + add_dmrs_flag = pucch_Config->format3->choice.setup->additionalDMRS ? 1 : 0; + if (pucchres->format.choice.format3->nrofSymbols == 4) + f3_dmrs_symbols = 1 << (pucchres->intraSlotFrequencyHopping ? 1 : 0); + else { + if (pucchres->format.choice.format3->nrofSymbols < 10) + f3_dmrs_symbols = 2; + else + f3_dmrs_symbols = 2 << add_dmrs_flag; + } + return f3_dmrs_symbols; +} + +uint16_t compute_pucch_prb_size(uint8_t format, + uint8_t nr_prbs, + uint16_t O_uci, + NR_PUCCH_MaxCodeRate_t *maxCodeRate, + uint8_t Qm, + uint8_t n_symb, + uint8_t n_re_ctrl) +{ + int O_crc = compute_pucch_crc_size(O_uci); + int O_tot = O_uci + O_crc; + + float r = get_max_code_rate(maxCodeRate); AssertFatal(O_tot <= (nr_prbs * n_re_ctrl * n_symb * Qm * r), "MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with %d PRBs", r, - O_tot, + O_uci, O_crc, nr_prbs); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 07daa617259bd3e357833bc27302aa98e7e20544..ab7a820612601c9de67b876f5e7488efaa1d0c73 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -244,6 +244,9 @@ uint16_t compute_pucch_prb_size(uint8_t format, uint8_t n_symb, uint8_t n_re_ctrl); +float get_max_code_rate(NR_PUCCH_MaxCodeRate_t *maxCodeRate); +int get_f3_dmrs_symbols(NR_PUCCH_Resource_t *pucchres, NR_PUCCH_Config_t *pucch_Config); + int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH); void find_period_offset_SR(const NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index da26cae863065c4fd45cf940d2d678d581542304..d4515ac235dbbec04744a3fb88bb44b2e5603922 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -707,7 +707,10 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, mac->si_SchedulingInfo = si_SchedulingInfo; mac->nr_band = *scc->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR; config_common_ue_sa(mac, scc, module_id, cc_idP); - configure_current_BWP(mac, scc, NULL); + // configure BWP only if it is a SIB1 detection in non connected state (after sync) + // not if it is a periodical update of SIB1 (no change of BWP in that case) + if(mac->state < UE_CONNECTED) + configure_current_BWP(mac, scc, NULL); // Setup the SSB to Rach Occasionsif (cell_group_config->spCellConfig) { mapping according to the config build_ssb_to_ro_map(mac); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 2259ae7cf14f4fdd4b1813aa7b271838a44de031..adc9353adaaac2e0f9c4218ed384ffa4fed911f6 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -47,7 +47,7 @@ void nr_ue_init_mac(module_id_t module_idP); \param mac mac instance */ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac); -int8_t nr_ue_decode_mib(module_id_t module_id, int cc_id); +void nr_ue_decode_mib(module_id_t module_id, int cc_id); /**\brief decode SIB1 and other SIs pdus in NR_UE, from if_module dl_ind \param module_id module id diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index a724c0f5746d8b4deceb6801a50b9f10b40ada9a..ea8af970099832a1b1c38ae43778f1ae3926d3e6 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -232,14 +232,20 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti) return rnti_type; } - -int8_t nr_ue_decode_mib(module_id_t module_id, - int cc_id) +void nr_ue_decode_mib(module_id_t module_id, int cc_id) { LOG_D(MAC,"[L2][MAC] decode mib\n"); - NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + if (mac->mib->cellBarred == NR_MIB__cellBarred_barred) { + LOG_W(MAC, "Cell is barred. Going back to sync mode.\n"); + mac->synch_request.Mod_id = module_id; + mac->synch_request.CC_id = cc_id; + mac->synch_request.synch_req.target_Nid_cell = -1; + mac->if_module->synch_request(&mac->synch_request); + return; + } + uint16_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused); uint16_t frame_number_4lsb = 0; @@ -285,8 +291,6 @@ int8_t nr_ue_decode_mib(module_id_t module_id, mac->state = UE_CONNECTED; else if(mac->state == UE_NOT_SYNC) mac->state = UE_SYNC; - - return 0; } int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 94aff89a564a1a116b6470f8e085521b3c41ffb5..6776ac6a4947499e8157f05908c82b6a770ce263 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2586,7 +2586,6 @@ static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_fr } // if is_nr_UL_slot } -#define MAX_LCID 8 // NR_MAX_NUM_LCID shall be used but the mac_rlc_data_req function can fetch data for max 8 LCID typedef struct { uint8_t bsr_len; uint8_t bsr_ce_len; @@ -2872,7 +2871,6 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, //mac_ce_p->phr_ce_len = 0; //mac_ce_p->phr_header_len = 0; - uint8_t lcid = 0; uint16_t sdu_length = 0; uint16_t num_sdus = 0; mac_ce_p->sdu_length_total = 0; @@ -2898,8 +2896,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization - for (lcid = UL_SCH_LCID_SRB1; lcid < MAX_LCID; lcid++) { - + for (int lcid = UL_SCH_LCID_SRB1; lcid < NR_MAX_NUM_LCID; lcid++) { buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d bytes, buflen_remain %d bytes)\n", diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 165251e9f423b1c48ea77a37aeb386cd25813ccb..bdf84ddc8eecf079b535ed5af275cbe138feeeaa 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1615,192 +1615,6 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); } -static void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP, - NR_RA_t *ra, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req) -{ - gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; - - // proceed only if it is a DL slot - if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) - return; - - // UE is known by the network, C-RNTI to be used instead of TC-RNTI - int rnti = ra->crnti; - - NR_UE_info_t *UE = find_nr_UE(&nr_mac->UE_info, rnti); - if (!UE) { - LOG_E(NR_MAC, "Received Msg3 with C-RNTI but rnti %04x not in the table\n", rnti); - return; - } - - NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_SearchSpace_t *ss = ra->ra_ss; - - NR_ControlResourceSet_t *coreset = ra->coreset; - AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n"); - - // Only need to schedule DCI with and empty DL - NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; - long BWPStart = 0; - long BWPSize = 0; - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; - if(*ss->controlResourceSetId!=0) { - BWPStart = dl_bwp->BWPStart; - BWPSize = dl_bwp->BWPSize; - } else { - type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; - BWPStart = type0_PDCCH_CSS_config->cset_start_rb; - BWPSize = type0_PDCCH_CSS_config->num_rbs; - } - - // get CCEindex, needed also for PUCCH and then later for PDCCH - uint8_t aggregation_level; - int CCEIndex = get_cce_index(nr_mac, - CC_id, slotP, 0, - &aggregation_level, - ss, - coreset, - &ra->sched_pdcch, - true); - - if (CCEIndex < 0) { - LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, rnti); - return; - } - - // Checking if the DCI allocation is feasible in current subframe - nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; - if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { - LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, rnti); - return; - } - - uint8_t time_domain_assignment = get_dl_tda(nr_mac, scc, slotP); - int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1; - NR_tda_info_t tda = get_dl_tda_info(dl_bwp, ss->searchSpaceType->present, time_domain_assignment, - scc->dmrs_TypeA_Position, mux_pattern, NR_RNTI_C, coreset->controlResourceSetId, false); - - NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, - dl_bwp, - &tda, - 1); - - int subheader_len = sizeof(NR_MAC_SUBHEADER_SHORT); - int pdu_length = subheader_len + 7; // 7 is contetion resolution length - - int mcsTableIdx = dl_bwp->mcsTableIdx; - int mcsIndex = 0; - int rbStart = 0; - int rbSize = 0; - int tb_scaling = 0; - uint32_t tb_size = 0; - - // increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size - do { - if(rbSize < BWPSize) - rbSize++; - else - mcsIndex++; - LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",dmrs_info.N_PRB_DMRS,dmrs_info.N_DMRS_SLOT); - tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx), - nr_get_code_rate_dl(mcsIndex, mcsTableIdx), - rbSize, tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, tb_scaling,1) >> 3; - } while (tb_size < pdu_length && mcsIndex<=28); - - AssertFatal(tb_size >= pdu_length,"Cannot allocate response to MSG3 with DCCH\n"); - - int i = 0; - uint16_t *vrb_map = cc[CC_id].vrb_map; - while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) { - if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(tda.startSymbolIndex, tda.nrOfSymbols)) { - rbStart += i+1; - i = 0; - } else { - i++; - } - } - - if (rbStart > (BWPSize - rbSize)) { - LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RNTI %04x!\n", __func__, rnti); - return; - } - - // Remove UE associated to TC-RNTI - mac_remove_nr_ue(nr_mac, ra->rnti); - - - // If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful if the UE receives a PDCCH transmission which has its CRC bits scrambled by the C-RNTI - // Just send padding LCID - uint8_t buf[tb_size]; - NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[0]; - padding->R = 0; - padding->LCID = DL_SCH_LCID_PADDING; - for(int k = 1; k < tb_size; k++) - buf[k] = 0; - - T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti), - T_INT(frameP), T_INT(slotP), T_INT(0), T_BUFFER(buf, tb_size)); - - // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control - // information to data and is reset every slot. - const int pduindex = nr_mac->pdu_index[CC_id]++; - - prepare_dl_pdus(nr_mac, ra, dl_bwp, dl_req, NULL, dmrs_info, tda, aggregation_level, CCEIndex, tb_size, 0, 0, 0, - 0, time_domain_assignment, CC_id, rnti, 0, mcsIndex, tb_scaling, pduindex, rbStart, rbSize); - - // DL TX request - nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs]; - memcpy(tx_req->TLVs[0].value.direct, buf, sizeof(uint8_t) * tb_size); - tx_req->PDU_length = tb_size; - tx_req->PDU_index = pduindex; - tx_req->num_TLV = 1; - tx_req->TLVs[0].length = tb_size + 2; - TX_req->SFN = frameP; - TX_req->Number_of_PDUs++; - TX_req->Slot = slotP; - - // Mark the corresponding symbols and RBs as used - fill_pdcch_vrb_map(nr_mac, - CC_id, - &ra->sched_pdcch, - CCEIndex, - aggregation_level); - for (int rb = 0; rb < rbSize; rb++) - vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(tda.startSymbolIndex, tda.nrOfSymbols); - - - // If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful upon transmission of PDCCH - LOG_A(NR_MAC, "(ue rnti 0x%04x) CBRA procedure succeeded!\n", ra->rnti); - nr_clear_ra_proc(module_idP, CC_id, frameP, ra); - UE->Msg4_ACKed = true; - UE->ra_timer = 0; - - if(!UE->CellGroup) { - // In the specific scenario where UE correctly received MSG4 (assuming it decoded RRCsetup with CellGroup) and gNB didn't correctly received an ACK, - // the UE would already have CG but the UE-dedicated gNB structure wouldn't (because RA didn't complete on gNB side). - uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, //might be added prefix later - (void **)&UE->CellGroup, - (uint8_t *)UE->cg_buf, - (UE->enc_rval.encoded+7)/8, 0, 0); - } - - process_CellGroup(UE->CellGroup, UE); - - // switching to initial BWP - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE, 0, 0); - - // Reset uplink failure flags/counters/timers at MAC so gNB will resume again scheduling resources for this UE - nr_mac_reset_ul_failure(sched_ctrl); -} - static void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, @@ -1814,8 +1628,7 @@ static void nr_generate_Msg4(module_id_t module_idP, NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; // if it is a DL slot, if the RA is in MSG4 state - if (is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP) && - ra->state == Msg4) { + if (is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) { NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_SearchSpace_t *ss = ra->ra_ss; @@ -1842,7 +1655,7 @@ static void nr_generate_Msg4(module_id_t module_idP, if (srb_status.bytes_in_buffer == 0) { lcid = DL_SCH_LCID_DCCH; - // Check for data on SRB1 (RRCReestablishment) + // Check for data on SRB1 (RRCReestablishment, RRCReconfiguration) srb_status = mac_rlc_status_ind(module_idP, ra->rnti, module_idP, frameP, slotP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, 0, 0); } @@ -1955,8 +1768,6 @@ static void nr_generate_Msg4(module_id_t module_idP, return; } - LOG_I(NR_MAC,"Generate msg4, rnti: %04x\n", ra->rnti); - // HARQ management if (current_harq_pid < 0) { AssertFatal(sched_ctrl->available_dl_harq.head >= 0, @@ -2011,7 +1822,6 @@ static void nr_generate_Msg4(module_id_t module_idP, ((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->L = htons(mac_sdu_length); ra->mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_LONG); } - LOG_I(NR_MAC,"Encoded RRCSetup Piggyback (%d + %d bytes), mac_pdu_length %d\n", mac_sdu_length, mac_subheader_len, ra->mac_pdu_length); memcpy(&buf[mac_pdu_length + mac_subheader_len], buffer, mac_sdu_length); } @@ -2054,7 +1864,7 @@ static void nr_generate_Msg4(module_id_t module_idP, } ra->state = WAIT_Msg4_ACK; - LOG_D(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); + LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); } } @@ -2113,7 +1923,6 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t ra->timing_offset = 0; ra->RRC_timer = 20; ra->msg3_round = 0; - ra->crnti = 0; if(ra->cfra == false) { ra->rnti = 0; } @@ -2271,7 +2080,7 @@ void nr_schedule_RA(module_id_t module_idP, nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req); break; case Msg3_dcch_dtch: - nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); + /* fallthrough */ case Msg4: nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); break; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 81ea2edcb7a76ebec78dbc623875462f33c47714..f475ed385aba2da3d5a89050013a161f6059e87d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -43,11 +43,13 @@ #include "UTIL/OPT/opt.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include "F1AP_CauseRadioNetwork.h" #include "RRC/NR/MESSAGES/asn1_msg.h" #include "intertask_interface.h" #include "openair2/F1AP/f1ap_ids.h" +#include "F1AP_CauseRadioNetwork.h" #include "T.h" @@ -812,23 +814,19 @@ int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset, } // This function configures pucch pdu fapi structure -void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, +void nr_configure_pucch(nfapi_nr_pucch_pdu_t *pucch_pdu, NR_ServingCellConfigCommon_t *scc, NR_UE_info_t *UE, uint8_t pucch_resource, uint16_t O_csi, uint16_t O_ack, uint8_t O_sr, - int r_pucch) { - + int r_pucch) +{ NR_PUCCH_Resource_t *pucchres; - NR_PUCCH_ResourceSet_t *pucchresset; NR_PUCCH_FormatConfig_t *pucchfmt; - NR_PUCCH_ResourceId_t *resource_id = NULL; NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; - int n_list, n_set; - uint16_t N2,N3; int res_found = 0; pucch_pdu->bit_len_harq = O_ack; @@ -884,60 +882,27 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, pucch_pdu->cyclic_prefix = (current_BWP->cyclicprefix==NULL) ? 0 : *current_BWP->cyclicprefix; NR_PUCCH_Config_t *pucch_Config = current_BWP->pucch_Config; - if (r_pucch<0 || pucch_Config) { - LOG_D(NR_MAC,"pucch_acknak: Filling dedicated configuration for PUCCH\n"); - - AssertFatal(pucch_Config->resourceSetToAddModList!=NULL, - "PUCCH resourceSetToAddModList is null\n"); - - n_set = pucch_Config->resourceSetToAddModList->list.count; - AssertFatal(n_set>0,"PUCCH resourceSetToAddModList is empty\n"); - - LOG_D(NR_MAC, "UCI n_set= %d\n", n_set); - - N2 = 2; - // procedure to select pucch resource id from resource sets according to - // number of uci bits and pucch resource indicator pucch_resource - // ( see table 9.2.3.2 in 38.213) - for (int i=0; i<n_set; i++) { - pucchresset = pucch_Config->resourceSetToAddModList->list.array[i]; - n_list = pucchresset->resourceList.list.count; - if (pucchresset->pucch_ResourceSetId == 0 && O_uci<3) { - if (pucch_resource < n_list) - resource_id = pucchresset->resourceList.list.array[pucch_resource]; - else - AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci); - } - if (pucchresset->pucch_ResourceSetId == 1 && O_uci>2) { - N3 = pucchresset->maxPayloadSize!= NULL ? *pucchresset->maxPayloadSize : 1706; - if (N2<O_uci && N3>O_uci) { - if (pucch_resource < n_list) - resource_id = pucchresset->resourceList.list.array[pucch_resource]; - else - AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci); - } - else N2 = N3; - } - } + if (r_pucch < 0 || pucch_Config) { + LOG_D(NR_MAC, "pucch_acknak: Filling dedicated configuration for PUCCH\n"); - AssertFatal(resource_id!=NULL,"Couldn-t find any matching PUCCH resource in the PUCCH resource sets"); + int resource_id = get_pucch_resourceid(pucch_Config, O_uci, pucch_resource); AssertFatal(pucch_Config->resourceToAddModList!=NULL, "PUCCH resourceToAddModList is null\n"); - n_list = pucch_Config->resourceToAddModList->list.count; - AssertFatal(n_list>0,"PUCCH resourceToAddModList is empty\n"); + int n_list = pucch_Config->resourceToAddModList->list.count; + AssertFatal(n_list > 0, "PUCCH resourceToAddModList is empty\n"); // going through the list of PUCCH resources to find the one indexed by resource_id - for (int i=0; i<n_list; i++) { + for (int i = 0; i < n_list; i++) { pucchres = pucch_Config->resourceToAddModList->list.array[i]; - if (pucchres->pucch_ResourceId == *resource_id) { + if (pucchres->pucch_ResourceId == resource_id) { res_found = 1; pucch_pdu->prb_start = pucchres->startingPRB; pucch_pdu->rnti = UE->rnti; // FIXME why there is only one frequency hopping flag // what about inter slot frequency hopping? - pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ? 1 : 0; + pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping ? 1 : 0; pucch_pdu->second_hop_prb = pucchres->secondHopPRB!= NULL ? *pucchres->secondHopPRB : 0; switch(pucchres->format.present) { case NR_PUCCH_Resource__format_PR_format0 : @@ -962,8 +927,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, pucch_pdu->sr_flag = O_sr; pucch_pdu->nr_of_symbols = pucchres->format.choice.format2->nrofSymbols; pucch_pdu->start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex; - pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId; - pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : *scc->physCellId; + pucch_pdu->data_scrambling_id = pusch_id ? *pusch_id : *scc->physCellId; + pucch_pdu->dmrs_scrambling_id = id0 ? *id0 : *scc->physCellId; pucch_pdu->prb_size = compute_pucch_prb_size(2, pucchres->format.choice.format2->nrofPRBs, O_uci + O_sr, @@ -977,25 +942,17 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, pucch_pdu->format_type = 3; pucch_pdu->nr_of_symbols = pucchres->format.choice.format3->nrofSymbols; pucch_pdu->start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex; - pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId; + pucch_pdu->data_scrambling_id = pusch_id ? *pusch_id : *scc->physCellId; if (pucch_Config->format3 == NULL) { pucch_pdu->pi_2bpsk = 0; pucch_pdu->add_dmrs_flag = 0; } else { pucchfmt = pucch_Config->format3->choice.setup; - pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0; - pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0; - } - int f3_dmrs_symbols; - if (pucchres->format.choice.format3->nrofSymbols==4) - f3_dmrs_symbols = 1<<pucch_pdu->freq_hop_flag; - else { - if(pucchres->format.choice.format3->nrofSymbols<10) - f3_dmrs_symbols = 2; - else - f3_dmrs_symbols = 2<<pucch_pdu->add_dmrs_flag; + pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK ? 1 : 0; + pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS ? 1 : 0; } + int f3_dmrs_symbols = get_f3_dmrs_symbols(pucchres, pucch_Config); pucch_pdu->prb_size = compute_pucch_prb_size(3, pucchres->format.choice.format3->nrofPRBs, O_uci + O_sr, @@ -1018,8 +975,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, } else { pucchfmt = pucch_Config->format3->choice.setup; - pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0; - pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0; + pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK != NULL; + pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS != NULL; } pucch_pdu->bit_len_csi_part1 = O_csi; break; @@ -1028,11 +985,17 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, } } } - AssertFatal(res_found==1,"No PUCCH resource found corresponding to id %ld\n",*resource_id); - LOG_D(NR_MAC,"Configure pucch: pucch_pdu->format_type %d pucch_pdu->bit_len_harq %d, pucch->pdu->bit_len_csi %d\n",pucch_pdu->format_type,pucch_pdu->bit_len_harq,pucch_pdu->bit_len_csi_part1); - } - else { // this is the default PUCCH configuration, PUCCH format 0 or 1 - LOG_D(NR_MAC,"pucch_acknak: Filling default PUCCH configuration from Tables (r_pucch %d, pucch_Config %p)\n",r_pucch,pucch_Config); + AssertFatal(res_found == 1, "No PUCCH resource found corresponding to id %d\n", resource_id); + LOG_D(NR_MAC, + "Configure pucch: pucch_pdu->format_type %d pucch_pdu->bit_len_harq %d, pucch->pdu->bit_len_csi %d\n", + pucch_pdu->format_type, + pucch_pdu->bit_len_harq, + pucch_pdu->bit_len_csi_part1); + } else { // this is the default PUCCH configuration, PUCCH format 0 or 1 + LOG_D(NR_MAC, + "pucch_acknak: Filling default PUCCH configuration from Tables (r_pucch %d, pucch_Config %p)\n", + r_pucch, + pucch_Config); int rsetindex = *pucch_ConfigCommon->pucch_ResourceCommon; int prb_start, second_hop_prb, nr_of_symb, start_symb; set_r_pucch_parms(rsetindex, @@ -1060,7 +1023,6 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, } } - void set_r_pucch_parms(int rsetindex, int r_pucch, int bwp_size, @@ -2985,12 +2947,33 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct * stop at 0 and we wait for a UE release command from upper layers */ if (sched_ctrl->ul_failure_timer == 1) { f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); - f1ap_ue_context_release_complete_t complete = { + f1ap_ue_context_release_req_t request = { .gNB_CU_ue_id = ue_data.secondary_ue, .gNB_DU_ue_id = rnti, .cause = F1AP_CAUSE_RADIO_NETWORK, - .cause_value = 12, // F1AP_CauseRadioNetwork_rl_failure_others + .cause_value = F1AP_CauseRadioNetwork_rl_failure_others, }; - nrmac->mac_rrc.ue_context_release_request(&complete); + nrmac->mac_rrc.ue_context_release_request(&request); } } + +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE) +{ + DevAssert(UE->CellGroup != NULL); + uint8_t buf[2048]; + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, UE->CellGroup, buf, sizeof(buf)); + AssertFatal(enc_rval.encoded > 0, "ASN1 encoding of CellGroupConfig failed, failed type %s\n", enc_rval.failed_type->name); + du_to_cu_rrc_information_t du2cu = { + .cellGroupConfig = buf, + .cellGroupConfig_length = (enc_rval.encoded + 7) >> 3, + }; + f1_ue_data_t ue_data = du_get_f1_ue_data(UE->rnti); + f1ap_ue_context_modif_required_t required = { + .gNB_CU_ue_id = ue_data.secondary_ue, + .gNB_DU_ue_id = UE->rnti, + .du_to_cu_rrc_information = &du2cu, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = F1AP_CauseRadioNetwork_action_desirable_for_radio_reasons, + }; + nrmac->mac_rrc.ue_context_modification_required(&required); +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index cf6001626d31270ad41dd9e45839ff04286dfa14..2ff175f34c918030e3c19478ee8f2dfb6e06eb73 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -234,7 +234,7 @@ void nr_csi_meas_reporting(int Mod_idP, const int sched_slot = (slot + ul_bwp->max_fb_time) % n_slots_frame; const int sched_frame = (frame + ((slot + ul_bwp->max_fb_time) / n_slots_frame)) % 1024; // prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214 - if ((sched_frame*n_slots_frame + sched_slot - offset)%period != 0) + if ((sched_frame * n_slots_frame + sched_slot - offset) % period != 0) continue; AssertFatal(is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[sched_slot / 64], sched_slot), "CSI reporting slot %d is not set for an uplink slot\n", sched_slot); @@ -280,7 +280,14 @@ void nr_csi_meas_reporting(int Mod_idP, len = pucchres->format.choice.format2->nrofPRBs; mask = SL_to_bitmap(pucchres->format.choice.format2->startingSymbolIndex, pucchres->format.choice.format2->nrofSymbols); curr_pucch->simultaneous_harqcsi = pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI; - LOG_D(NR_MAC,"%d.%d Allocating PUCCH format 2, startPRB %d, nPRB %d, simulHARQ %d, num_bits %d\n", sched_frame, sched_slot,start,len,curr_pucch->simultaneous_harqcsi,curr_pucch->csi_bits); + LOG_D(NR_MAC, + "%d.%d Allocating PUCCH format 2, startPRB %d, nPRB %d, simulHARQ %d, num_bits %d\n", + sched_frame, + sched_slot, + start, + len, + curr_pucch->simultaneous_harqcsi, + curr_pucch->csi_bits); break; case NR_PUCCH_Resource__format_PR_format3: len = pucchres->format.choice.format3->nrofPRBs; @@ -297,7 +304,12 @@ void nr_csi_meas_reporting(int Mod_idP, // verify resources are free for (int i = start; i < start + len; ++i) { if((vrb_map_UL[i+bwp_start] & mask) != 0) { - LOG_E(NR_MAC, "%4d.%2d VRB MAP in %4d.%2d not free. Can't schedule CSI reporting on PUCCH.\n", frame, slot, sched_frame, sched_slot); + LOG_E(NR_MAC, + "%4d.%2d VRB MAP in %4d.%2d not free. Can't schedule CSI reporting on PUCCH.\n", + frame, + slot, + sched_frame, + sched_slot); memset(curr_pucch, 0, sizeof(*curr_pucch)); } else @@ -308,6 +320,52 @@ void nr_csi_meas_reporting(int Mod_idP, } } +int get_pucch_resourceid(NR_PUCCH_Config_t *pucch_Config, int O_uci, int pucch_resource) +{ + NR_PUCCH_ResourceId_t *resource_id = NULL; + AssertFatal(pucch_Config->resourceSetToAddModList != NULL, "PUCCH resourceSetToAddModList is null\n"); + + int n_set = pucch_Config->resourceSetToAddModList->list.count; + AssertFatal(n_set > 0, "PUCCH resourceSetToAddModList is empty\n"); + + LOG_D(NR_MAC, "UCI n_set= %d\n", n_set); + + int N2 = 2; + // procedure to select pucch resource id from resource sets according to + // number of uci bits and pucch resource indicator pucch_resource + // ( see table 9.2.3.2 in 38.213) + for (int i = 0; i < n_set; i++) { + NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[i]; + int n_list = pucchresset->resourceList.list.count; + if (pucchresset->pucch_ResourceSetId == 0 && O_uci < 3) { + if (pucch_resource < n_list) + resource_id = pucchresset->resourceList.list.array[pucch_resource]; + else + AssertFatal(1 == 0, + "Couldn't find pucch resource indicator %d in PUCCH resource set %d for %d UCI bits", + pucch_resource, + i, + O_uci); + } + if (pucchresset->pucch_ResourceSetId == 1 && O_uci > 2) { + int N3 = pucchresset->maxPayloadSize != NULL ? *pucchresset->maxPayloadSize : 1706; + if (N2 < O_uci && N3 > O_uci) { + if (pucch_resource < n_list) + resource_id = pucchresset->resourceList.list.array[pucch_resource]; + else + AssertFatal(1 == 0, + "Couldn't find pucch resource indicator %d in PUCCH resource set %d for %d UCI bits", + pucch_resource, + i, + O_uci); + } else + N2 = N3; + } + } + AssertFatal(resource_id != NULL, "Couldn't find any matching PUCCH resource in the PUCCH resource sets"); + return *resource_id; +} + static void handle_dl_harq(NR_UE_info_t * UE, int8_t harq_pid, bool success, @@ -894,7 +952,8 @@ static NR_UE_harq_t *find_harq(frame_t frame, sub_frame_t slot, NR_UE_info_t * U while (harq->feedback_frame != frame || (harq->feedback_frame == frame && harq->feedback_slot < slot)) { LOG_W(NR_MAC, - "expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the past)\n", + "UE %04x expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the past)\n", + UE->rnti, pid, harq->feedback_frame, harq->feedback_slot, @@ -910,7 +969,8 @@ static NR_UE_harq_t *find_harq(frame_t frame, sub_frame_t slot, NR_UE_info_t * U /* feedbacks that we wait for in the future: don't do anything */ if (harq->feedback_slot > slot) { LOG_W(NR_MAC, - "expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the future)\n", + "UE %04x expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the future)\n", + UE->rnti, pid, harq->feedback_frame, harq->feedback_slot, @@ -943,7 +1003,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; NR_UE_harq_t *harq = find_harq(frame, slot, UE, nrmac->dl_bler.harq_round_max); if (!harq) { - LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__); + LOG_E(NR_MAC, "UE %04x: Could not find a HARQ process at %4d.%2d!\n", UE->rnti, frame, slot); break; } DevAssert(harq->is_waiting); @@ -1094,6 +1154,51 @@ static void set_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, uint16_t *v } } +bool check_bits_vs_coderate_limit(NR_PUCCH_Config_t *pucch_Config, int O_uci, int pucch_resource) +{ + int resource_id = get_pucch_resourceid(pucch_Config, O_uci, pucch_resource); + AssertFatal(pucch_Config->resourceToAddModList != NULL, "PUCCH resourceToAddModList is null\n"); + + int n_list = pucch_Config->resourceToAddModList->list.count; + AssertFatal(n_list > 0, "PUCCH resourceToAddModList is empty\n"); + + // going through the list of PUCCH resources to find the one indexed by resource_id + for (int i = 0; i < n_list; i++) { + NR_PUCCH_Resource_t *pucchres = pucch_Config->resourceToAddModList->list.array[i]; + if (pucchres->pucch_ResourceId == resource_id) { + NR_PUCCH_MaxCodeRate_t *maxCodeRate = NULL; + int nb_symbols = 0; + int prbs = 0; + int n_re_ctrl = 0; + int Qm = 0; + switch (pucchres->format.present) { + case NR_PUCCH_Resource__format_PR_format2: + prbs = pucchres->format.choice.format2->nrofPRBs; + maxCodeRate = pucch_Config->format2->choice.setup->maxCodeRate; + nb_symbols = pucchres->format.choice.format2->nrofSymbols; + n_re_ctrl = 8; + Qm = 2; + break; + case NR_PUCCH_Resource__format_PR_format3: + prbs = pucchres->format.choice.format3->nrofPRBs; + maxCodeRate = pucch_Config->format3->choice.setup->maxCodeRate; + int f3_dmrs_symbols = get_f3_dmrs_symbols(pucchres, pucch_Config); + nb_symbols = pucchres->format.choice.format3->nrofSymbols - f3_dmrs_symbols; + n_re_ctrl = 12; + Qm = pucch_Config->format3 ? (pucch_Config->format3->choice.setup->pi2BPSK ? 1 : 2) : 2; + break; + default: + AssertFatal(false, "PUCCH format %d not handled\n", pucchres->format.present); + } + int O_crc = compute_pucch_crc_size(O_uci); + int O_tot = O_uci + O_crc; + float r = get_max_code_rate(maxCodeRate); + return (O_tot <= (prbs * n_re_ctrl * nb_symbols * Qm * r)); + } + } + AssertFatal(false, "No PUCCH resource found\n"); +} + // this function returns an index to NR_sched_pucch structure // if the function returns -1 it was not possible to schedule acknack int nr_acknack_scheduling(gNB_MAC_INST *mac, @@ -1151,8 +1256,17 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, curr_pucch->dai_c == 2) continue; // if there is CSI but simultaneous HARQ+CSI is disable we can't schedule - if(curr_pucch->csi_bits > 0 && - !curr_pucch->simultaneous_harqcsi) + if (curr_pucch->csi_bits > 0 && !curr_pucch->simultaneous_harqcsi) + continue; + // check if the number of bits to be scheduled can fit in current PUCCH + // according to PUCCH code rate (if not we search for another allocation) + // the number of bits in the check need to include possible SR (1 bit) + // and the ack/nack bit to be scheduled (1 bit) + // so the number of bits already scheduled in current pucch + 2 + if (curr_pucch->csi_bits > 0 + && !check_bits_vs_coderate_limit(pucch_Config, + curr_pucch->csi_bits + curr_pucch->dai_c + 2, + curr_pucch->resource_indicator)) continue; // otherwise we can schedule in this active PUCCH diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 78d3397e6075b574c666ca3cd8268e95b7ee8861..cb42680ae9cd65bd62b01574414003d259a8f2bd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -223,9 +223,14 @@ static int nr_process_mac_pdu(instance_t module_idP, for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i]; if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) { - ra->crnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF); + // remove UE context just created after Msg.3 in some milliseconds + // as the UE is one already known (not now, as the UE context is + // still needed for the moment) + nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); + //mac_remove_nr_ue(RC.nrmac[module_idP], ra->rnti); + // this UE is the one identified by the RNTI in pduP + ra->rnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF); ra->state = Msg3_dcch_dtch; - LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x\n", ra->crnti); break; } } @@ -780,12 +785,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (ra->state == Msg3_dcch_dtch) { // Check if the UE identified by C-RNTI still exists at the gNB - NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->crnti); + NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->rnti); if (!UE_C) { // The UE identified by C-RNTI no longer exists at the gNB // Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better solution may be implemented mac_remove_nr_ue(gNB_mac, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg.3 to have UE come back with new RA attempt\n", ra->rnti); return; } else { // The UE identified by C-RNTI still exists at the gNB @@ -794,9 +800,11 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // Reset HARQ processes reset_dl_harq_list(&UE_C->UE_sched_ctrl); reset_ul_harq_list(&UE_C->UE_sched_ctrl); + + // Trigger RRC Reconfiguration + LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE_C->rnti); + nr_mac_trigger_reconfiguration(RC.nrmac[gnb_mod_idP], UE_C); } - LOG_I(NR_MAC, "Activating scheduling response to MSG3 with DCCH/DTCCH and RNTI 0x%04x (state %d)\n", - ra->crnti, ra->state); } else { LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %d)\n", diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 10ba95928dff73a1eb75254fe8cc78afa839664d..15d823aaf2e10b9a0a22d13a7f9cf350e5f69a28 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -170,6 +170,8 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr const NR_UE_UL_BWP_t *current_BWP, uint8_t *ul_ri); +int get_pucch_resourceid(NR_PUCCH_Config_t *pucch_Config, int O_uci, int pucch_resource); + void nr_schedule_srs(int module_id, frame_t frame, int slot); void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slots_frame, nfapi_nr_dl_tti_request_t *DL_req); @@ -447,4 +449,6 @@ void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpac void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl); void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 0a450a11983532aedb0e1612565784a481166672..e78b66fdedeed88d27682bcfbce498f744695b79 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -25,6 +25,7 @@ #include "openair2/F1AP/f1ap_ids.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/RRC/NR/MESSAGES/asn1_msg.h" +#include "F1AP_CauseRadioNetwork.h" #include "uper_decoder.h" #include "uper_encoder.h" @@ -243,6 +244,63 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) } } +void ue_context_modification_confirm(const f1ap_ue_context_modif_confirm_t *confirm) +{ + LOG_I(MAC, "Received UE Context Modification Confirm for UE %04x\n", confirm->gNB_DU_ue_id); + + gNB_MAC_INST *mac = RC.nrmac[0]; + NR_SCHED_LOCK(&mac->sched_lock); + /* check first that the scheduler knows such UE */ + NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, confirm->gNB_DU_ue_id); + if (UE == NULL) { + LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring UE Context Modification Confirm\n", confirm->gNB_DU_ue_id); + NR_SCHED_UNLOCK(&mac->sched_lock); + return; + } + NR_SCHED_UNLOCK(&mac->sched_lock); + + if (confirm->rrc_container_length > 0) + nr_rlc_srb_recv_sdu(confirm->gNB_DU_ue_id, DCCH, confirm->rrc_container, confirm->rrc_container_length); + + /* nothing else to be done? */ +} + +void ue_context_modification_refuse(const f1ap_ue_context_modif_refuse_t *refuse) +{ + /* Currently, we only use the UE Context Modification Required procedure to + * trigger a RRC reconfigurtion after Msg.3 with C-RNTI MAC CE. If the CU + * refuses, it cannot do this reconfiguration, leaving the UE in an + * unconfigured state. Therefore, we just free all RA-related info, and + * request the release of the UE. */ + LOG_W(MAC, "Received UE Context Modification Refuse for %04x, requesting release\n", refuse->gNB_DU_ue_id); + + gNB_MAC_INST *mac = RC.nrmac[0]; + NR_SCHED_LOCK(&mac->sched_lock); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, refuse->gNB_DU_ue_id); + if (UE == NULL) { + LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring UE Context Modification Refuse\n", refuse->gNB_DU_ue_id); + NR_SCHED_UNLOCK(&mac->sched_lock); + return; + } + + const int CC_id = 0; + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + if (ra->rnti == UE->rnti) + nr_clear_ra_proc(0, CC_id, 0 /* frame */, ra); + } + NR_SCHED_UNLOCK(&mac->sched_lock); + + f1ap_ue_context_release_req_t request = { + .gNB_CU_ue_id = refuse->gNB_CU_ue_id, + .gNB_DU_ue_id = refuse->gNB_DU_ue_id, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = F1AP_CauseRadioNetwork_procedure_cancelled, + }; + mac->mac_rrc.ue_context_release_request(&request); +} + void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) { /* mark UE as to be deleted after PUSCH failure */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 859e128b4a8f04b3f9bd4d5247a1177988b5ae01..ebe6ba5adc126093f70400ac665274514032e40d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -27,6 +27,8 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req); void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req); +void ue_context_modification_confirm(const f1ap_ue_context_modif_confirm_t *confirm); +void ue_context_modification_refuse(const f1ap_ue_context_modif_refuse_t *refuse); void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd); void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h index 5d7a7cd644b6ae18a022223eb165383300f9033a..43a4818e93313fa3d318d66a19ef770ef9b5d07f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -28,6 +28,7 @@ typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp); typedef void (*ue_context_modification_response_func_t)(const f1ap_ue_context_modif_req_t *req, const f1ap_ue_context_modif_resp_t *resp); +typedef void (*ue_context_modification_required_func_t)(const f1ap_ue_context_modif_required_t *t); typedef void (*ue_context_release_request_func_t)(const f1ap_ue_context_release_req_t* req); typedef void (*ue_context_release_complete_func_t)(const f1ap_ue_context_release_complete_t *complete); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index a024abe6afc0ce24ce2b53e96817deb16e97ed3b..dab70b5e821d377c197091830f59af7e8e414c31 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -111,6 +111,31 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_ itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } +static void ue_context_modification_required_direct(const f1ap_ue_context_modif_required_t *required) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED); + f1ap_ue_context_modif_required_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg); + f1ap_msg->gNB_CU_ue_id = required->gNB_CU_ue_id; + f1ap_msg->gNB_DU_ue_id = required->gNB_DU_ue_id; + f1ap_msg->du_to_cu_rrc_information = NULL; + if (required->du_to_cu_rrc_information != NULL) { + f1ap_msg->du_to_cu_rrc_information = calloc(1, sizeof(*f1ap_msg->du_to_cu_rrc_information)); + AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); + du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information; + AssertFatal(required->du_to_cu_rrc_information->cellGroupConfig != NULL && required->du_to_cu_rrc_information->cellGroupConfig_length > 0, + "cellGroupConfig is mandatory\n"); + du2cu->cellGroupConfig_length = required->du_to_cu_rrc_information->cellGroupConfig_length; + du2cu->cellGroupConfig = malloc(du2cu->cellGroupConfig_length * sizeof(*du2cu->cellGroupConfig)); + AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n"); + memcpy(du2cu->cellGroupConfig, required->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length); + AssertFatal(required->du_to_cu_rrc_information->measGapConfig == NULL && required->du_to_cu_rrc_information->measGapConfig_length == 0, "not handled yet\n"); + AssertFatal(required->du_to_cu_rrc_information->requestedP_MaxFR1 == NULL && required->du_to_cu_rrc_information->requestedP_MaxFR1_length == 0, "not handled yet\n"); + } + f1ap_msg->cause = required->cause; + f1ap_msg->cause_value = required->cause_value; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); +} + static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); @@ -151,6 +176,7 @@ void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_direct; mac_rrc->ue_context_modification_response = ue_context_modification_response_direct; + mac_rrc->ue_context_modification_required = ue_context_modification_required_direct; mac_rrc->ue_context_release_request = ue_context_release_request_direct; mac_rrc->ue_context_release_complete = ue_context_release_complete_direct; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index 644decc21cf6889ea470bf7d32bcd7a42118c8fb..c873c569e5eb94f1fa5472455fc8b85da55296bc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -96,6 +96,31 @@ static void ue_context_modification_response_f1ap(const f1ap_ue_context_modif_re itti_send_msg_to_task(TASK_DU_F1, 0, msg); } +static void ue_context_modification_required_f1ap(const f1ap_ue_context_modif_required_t *required) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED); + f1ap_ue_context_modif_required_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg); + f1ap_msg->gNB_CU_ue_id = required->gNB_CU_ue_id; + f1ap_msg->gNB_DU_ue_id = required->gNB_DU_ue_id; + f1ap_msg->du_to_cu_rrc_information = NULL; + if (required->du_to_cu_rrc_information != NULL) { + f1ap_msg->du_to_cu_rrc_information = calloc(1, sizeof(*f1ap_msg->du_to_cu_rrc_information)); + AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); + du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information; + AssertFatal(required->du_to_cu_rrc_information->cellGroupConfig != NULL && required->du_to_cu_rrc_information->cellGroupConfig_length > 0, + "cellGroupConfig is mandatory\n"); + du2cu->cellGroupConfig_length = required->du_to_cu_rrc_information->cellGroupConfig_length; + du2cu->cellGroupConfig = malloc(du2cu->cellGroupConfig_length * sizeof(*du2cu->cellGroupConfig)); + AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n"); + memcpy(du2cu->cellGroupConfig, required->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length); + AssertFatal(required->du_to_cu_rrc_information->measGapConfig == NULL && required->du_to_cu_rrc_information->measGapConfig_length == 0, "not handled yet\n"); + AssertFatal(required->du_to_cu_rrc_information->requestedP_MaxFR1 == NULL && required->du_to_cu_rrc_information->requestedP_MaxFR1_length == 0, "not handled yet\n"); + } + f1ap_msg->cause = required->cause; + f1ap_msg->cause_value = required->cause_value; + itti_send_msg_to_task(TASK_DU_F1, 0, msg); +} + static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); @@ -138,6 +163,7 @@ void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap; mac_rrc->ue_context_modification_response = ue_context_modification_response_f1ap; + mac_rrc->ue_context_modification_required = ue_context_modification_required_f1ap; mac_rrc->ue_context_release_request = ue_context_release_request_f1ap; mac_rrc->ue_context_release_complete = ue_context_release_complete_f1ap; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 457497679a7303b8b998e0fbd782b9b92828c3f5..4bec3664c846819fa935e14b7101756714830ea3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -204,8 +204,6 @@ typedef struct { NR_CellGroupConfig_t *CellGroup; /// Preambles for contention-free access NR_preamble_ue_t preambles; - /// NSA: the UEs C-RNTI to use - rnti_t crnti; /// CFRA flag bool cfra; // BWP for RA @@ -660,6 +658,7 @@ typedef struct NR_bler_options { typedef struct nr_mac_rrc_ul_if_s { ue_context_setup_response_func_t ue_context_setup_response; ue_context_modification_response_func_t ue_context_modification_response; + ue_context_modification_required_func_t ue_context_modification_required; ue_context_release_request_func_t ue_context_release_request; ue_context_release_complete_func_t ue_context_release_complete; initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 7a2d3ae0a5525d5881fb727b74062fefbdfdbf43..3f8a298f9e652dd5a16bf61ce6a18fdddf2d517d 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -54,15 +54,17 @@ static uint64_t nr_rlc_current_time; static int nr_rlc_current_time_last_frame; static int nr_rlc_current_time_last_subframe; -nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, - logical_chan_id_t channel_id) +static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id) { if (channel_id == 0) return ue->srb0; nr_rlc_rb_t *rb = &ue->lcid2rb[channel_id - 1]; - if (rb->type == NR_RLC_SRB) + if (rb->type == NR_RLC_NONE) + return NULL; + if (rb->type == NR_RLC_SRB) { + AssertFatal(rb->choice.srb_id > 0, "logic bug: impossible to have srb0 here\n"); return ue->srb[rb->choice.srb_id - 1]; - else { + } else { AssertFatal(rb->type == NR_RLC_DRB, "Invalid RB type\n"); return ue->drb[rb->choice.drb_id - 1]; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h index 5c7c58e3eebc342a6859b943c6f5bd9ebffec109..ed29c5458b5f59a58cc1a3c0fcc8b08bac8c8c73 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -27,10 +27,7 @@ typedef void nr_rlc_ue_manager_t; -typedef enum nr_rlc_rb_type { - NR_RLC_SRB = 0, - NR_RLC_DRB = 1 -} nr_rlc_rb_type; +typedef enum nr_rlc_rb_type { NR_RLC_NONE = 0, NR_RLC_SRB = 1, NR_RLC_DRB = 2 } nr_rlc_rb_type; typedef struct nr_rlc_rb_t { nr_rlc_rb_type type; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 6b78e27f636e1311a0be61fa2a73a2f847bd60d7..d7812df89ec5c6f10e1cd8bfbaedaeb124b86b8d 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3842,7 +3842,7 @@ void rrc_eNB_handover_ue_context_release( ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; } - gtpv1u_delete_s1u_tunnel(ctxt_pP->module_id, &delete_tunnels); + gtpv1u_delete_all_s1u_tunnel(ctxt_pP->module_id, delete_tunnels.rnti); struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 94920f6f64a223fdcc95a92deb8001d1282267dd..0180f972fe01a5182ea52ada9762c0509866bdaf 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -27,6 +27,8 @@ typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req); typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req); +typedef void (*ue_context_modification_confirm_func_t)(const f1ap_ue_context_modif_confirm_t *confirm); +typedef void (*ue_context_modification_refuse_func_t)(const f1ap_ue_context_modif_refuse_t *refuse); typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); typedef void (*dl_rrc_message_transfer_func_t)(const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index eeec72e1328015b8de6099fef3dc5caea5cef077..423eac2462f5e047ab4a4cea28d675f47dd822d1 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -28,6 +28,8 @@ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request; mac_rrc->ue_context_modification_request = ue_context_modification_request; + mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm; + mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse; mac_rrc->ue_context_release_command = ue_context_release_command; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 3f3b0f800f0b7750b453054bccf4a1f296c38720..40eea4861c27dd8319d97bee4d33036c26acaf90 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -71,6 +71,31 @@ static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req itti_send_msg_to_task(TASK_CU_F1, 0, msg); } +static void ue_context_modification_confirm_f1ap(const f1ap_ue_context_modif_confirm_t *confirm) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_CONFIRM); + f1ap_ue_context_modif_confirm_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(msg); + f1ap_msg->gNB_CU_ue_id = confirm->gNB_CU_ue_id; + f1ap_msg->gNB_DU_ue_id = confirm->gNB_DU_ue_id; + f1ap_msg->rrc_container = NULL; + f1ap_msg->rrc_container_length = 0; + if (confirm->rrc_container != NULL) { + f1ap_msg->rrc_container = calloc(1, sizeof(*f1ap_msg->rrc_container)); + AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n"); + memcpy(f1ap_msg->rrc_container, confirm->rrc_container, confirm->rrc_container_length); + f1ap_msg->rrc_container_length = confirm->rrc_container_length; + } + itti_send_msg_to_task(TASK_CU_F1, 0, msg); +} + +static void ue_context_modification_refuse_f1ap(const f1ap_ue_context_modif_refuse_t *refuse) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REFUSE); + f1ap_ue_context_modif_refuse_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(msg); + *f1ap_msg = *refuse; + itti_send_msg_to_task(TASK_CU_F1, 0, msg); +} + static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd) { MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); @@ -110,6 +135,8 @@ void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap; mac_rrc->ue_context_modification_request = ue_context_modification_request_f1ap; + mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm_f1ap; + mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse_f1ap; mac_rrc->ue_context_release_command = ue_context_release_command_f1ap; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap; } diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index f9c821736c0aebfd5fea2f25df562708df93a18a..35ff70937801015b15853cd5a21db8d91fdc3be7 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -365,6 +365,8 @@ typedef struct { typedef struct nr_mac_rrc_dl_if_s { ue_context_setup_request_func_t ue_context_setup_request; ue_context_modification_request_func_t ue_context_modification_request; + ue_context_modification_confirm_func_t ue_context_modification_confirm; + ue_context_modification_refuse_func_t ue_context_modification_refuse; ue_context_release_command_func_t ue_context_release_command; dl_rrc_message_transfer_func_t dl_rrc_message_transfer; } nr_mac_rrc_dl_if_t; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 1fa458a309be3f518085d0c424477e013acf64c8..3df2b3614244f4fc2315afb126ff7e77b168d49b 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -43,7 +43,6 @@ #include "rrc_gNB_radio_bearers.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -#include "LAYER2/RLC/rlc.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "common/utils/LOG/log.h" #include "COMMON/mac_rrc_primitives.h" @@ -68,7 +67,6 @@ #include "uper_encoder.h" #include "uper_decoder.h" -#include "rlc.h" #include "platform_types.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -188,26 +186,6 @@ static void freeDRBlist(NR_DRB_ToAddModList_t *list) return; } -static void nr_rrc_addmod_drbs(int rnti, - const NR_DRB_ToAddModList_t *drb_list, - const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list) -{ - if (drb_list == NULL || bearer_list == NULL) - return; - - for (int i = 0; i < drb_list->list.count; i++) { - const NR_DRB_ToAddMod_t *drb = drb_list->list.array[i]; - for (int j = 0; j < bearer_list->list.count; j++) { - const NR_RLC_BearerConfig_t *bearer = bearer_list->list.array[j]; - if (bearer->servedRadioBearer != NULL - && bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity - && drb->drb_Identity == bearer->servedRadioBearer->choice.drb_Identity) { - nr_rlc_add_drb(rnti, drb->drb_Identity, bearer); - } - } - } -} - typedef struct deliver_dl_rrc_message_data_s { const gNB_RRC_INST *rrc; f1ap_dl_rrc_message_t *dl_rrc; @@ -994,14 +972,6 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co kUPint, get_softmodem_params()->sa ? ue_p->masterCellGroup->rlc_BearerToAddModList : NULL); - /* Refresh DRBs */ - if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { - LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %04x\n",ue_context_pP->ue_context.rnti); - const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list = - ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList; - nr_rrc_addmod_drbs(ctxt_pP->rntiMaybeUEid, DRB_configList, bearer_list); - } - /* Loop through DRBs and establish if necessary */ if (DRB_configList != NULL) { for (int i = 0; i < DRB_configList->list.count; i++) { @@ -1219,6 +1189,7 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + ue_p->xids[xid] = RRC_DEDICATED_RECONF; NR_CellGroupConfig_t *masterCellGroup = ue_p->masterCellGroup; if (dl_bwp_id > 0) { @@ -1247,18 +1218,22 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP NULL, masterCellGroup); - nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, masterCellGroup); - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { - uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated + nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, masterCellGroup); + + uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig + && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS; - nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms); + nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, + ue_p->rnti, + *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, + delay_ms); } return 0; @@ -1711,6 +1686,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); break; case RRC_REESTABLISH_COMPLETE: + case RRC_DEDICATED_RECONF: /* do nothing */ break; default: @@ -2131,6 +2107,69 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i } } +static void rrc_CU_process_ue_modification_required(MessageDef *msg_p) +{ + 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); + f1ap_ue_context_modif_refuse_t refuse = { + .gNB_CU_ue_id = required->gNB_CU_ue_id, + .gNB_DU_ue_id = required->gNB_DU_ue_id, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_cu_ue_f1ap_id, + }; + rrc->mac_rrc.ue_context_modification_refuse(&refuse); + return; + } + + if (required->du_to_cu_rrc_information && required->du_to_cu_rrc_information->cellGroupConfig) { + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + LOG_I(RRC, + "UE Context Modification Required: new CellGroupConfig for UE ID %d/RNTI %04x, triggering reconfiguration\n", + UE->rrc_ue_id, + UE->rnti); + + NR_CellGroupConfig_t *cellGroupConfig = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&cellGroupConfig, + (uint8_t *)required->du_to_cu_rrc_information->cellGroupConfig, + required->du_to_cu_rrc_information->cellGroupConfig_length); + if (dec_rval.code != RC_OK && dec_rval.consumed == 0) { + LOG_E(RRC, "Cell group config decode error, refusing reconfiguration\n"); + f1ap_ue_context_modif_refuse_t refuse = { + .gNB_CU_ue_id = required->gNB_CU_ue_id, + .gNB_DU_ue_id = required->gNB_DU_ue_id, + .cause = F1AP_CAUSE_PROTOCOL, + .cause_value = F1AP_CauseProtocol_transfer_syntax_error, + }; + rrc->mac_rrc.ue_context_modification_refuse(&refuse); + return; + } + + if (UE->masterCellGroup) { + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); + LOG_I(RRC, "UE %d/RNTI %04x replacing existing CellGroupConfig with new one received from DU\n", UE->rrc_ue_id, UE->rnti); + } + UE->masterCellGroup = cellGroupConfig; + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + 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); + //rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p); + return; + } + LOG_W(RRC, + "nothing to be done after UE Context Modification Required for UE ID %d/RNTI %04x\n", + required->gNB_CU_ue_id, + required->gNB_DU_ue_id); +} + unsigned int mask_flip(unsigned int x) { return((((x>>8) + (x<<8))&0xffff)>>6); } @@ -2598,6 +2637,10 @@ void *rrc_gnb_task(void *args_p) { rrc_CU_process_ue_context_modification_response(msg_p, instance); break; + case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED: + rrc_CU_process_ue_modification_required(msg_p); + break; + case F1AP_UE_CONTEXT_RELEASE_REQ: rrc_CU_process_ue_context_release_request(msg_p); break; diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index f0d89051df414bd0dd47e901b408928093a6d72d..359d25ae4e68aa60b22be297e30828834a66eab6 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -432,7 +432,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { memset(&ue_context->ue_context.nsa_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.nsa_gtp_addrs[e_rab])); ue_context->ue_context.nsa_gtp_ebi[e_rab] = 0; } - gtpv1u_delete_s1u_tunnel(rrc->module_id, &tmp); + gtpv1u_delete_all_s1u_tunnel(rrc->module_id, rnti); /* remove context */ rrc_gNB_remove_ue_context(rrc, ue_context); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 73c3fa15939c98a32abd28a4d0295ba988596d61..48700e564c8812f6c058e778e8b11b4188d37987 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -431,55 +431,55 @@ bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) { switch (si_type) { case NR_SIB_TypeInfo__type_sibType2: - if (!SI_info->sib2) + if (!SI_info->sib2 || SI_info->sib2_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType3: - if (!SI_info->sib3) + if (!SI_info->sib3 || SI_info->sib3_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType4: - if (!SI_info->sib4) + if (!SI_info->sib4 || SI_info->sib4_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType5: - if (!SI_info->sib5) + if (!SI_info->sib5 || SI_info->sib5_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType6: - if (!SI_info->sib6) + if (!SI_info->sib6 || SI_info->sib6_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType7: - if (!SI_info->sib7) + if (!SI_info->sib7 || SI_info->sib7_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType8: - if (!SI_info->sib8) + if (!SI_info->sib8 || SI_info->sib8_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType9: - if (!SI_info->sib9) + if (!SI_info->sib9 || SI_info->sib9_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType10_v1610: - if (!SI_info->sib10) + if (!SI_info->sib10 || SI_info->sib10_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType11_v1610: - if (!SI_info->sib11) + if (!SI_info->sib11 || SI_info->sib11_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType12_v1610: - if (!SI_info->sib12) + if (!SI_info->sib12 || SI_info->sib12_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType13_v1610: - if (!SI_info->sib13) + if (!SI_info->sib13 || SI_info->sib13_timer == -1) return false; break; case NR_SIB_TypeInfo__type_sibType14_v1610: - if (!SI_info->sib14) + if (!SI_info->sib14 || SI_info->sib14_timer == -1) return false; break; default : @@ -490,10 +490,9 @@ bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) int check_si_status(NR_UE_RRC_SI_INFO *SI_info) { - if (!get_softmodem_params()->sa) - return 0; // schedule reception of SIB1 if RRC doesn't have it - if (!SI_info->sib1) + // or if the timer expired + if (!SI_info->sib1 || SI_info->sib1_timer == -1) return 1; else { if (SI_info->sib1->si_SchedulingInfo) { @@ -534,9 +533,12 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const u NR_UE_rrc_inst[module_id].mib = bcch_message->message.choice.mib; bcch_message->message.choice.mib = NULL; - NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[module_id].SInfo[gNB_index]; - // to schedule MAC to get SI if required - int get_sib = check_si_status(SI_info); + int get_sib = 0; + if (get_softmodem_params()->sa && NR_UE_rrc_inst[module_id].mib->cellBarred == NR_MIB__cellBarred_notBarred) { + NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[module_id].SInfo[gNB_index]; + // to schedule MAC to get SI if required + get_sib = check_si_status(SI_info); + } nr_rrc_mac_config_req_mib(module_id, 0, NR_UE_rrc_inst[module_id].mib, get_sib); ret = 0; } @@ -770,8 +772,9 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) { switch (bcch_message->message.choice.c1->present) { case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: - if(SI_info->sib1 != NULL) - SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)SI_info->sib1, 1); + LOG_D(NR_RRC, "[UE %"PRIu8"] Decoding SIB1\n", module_id); + if(SI_info->sib1) + ASN_STRUCT_FREE(asn_DEF_NR_SIB1, SI_info->sib1); NR_SIB1_t *sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; SI_info->sib1 = sib1; if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index b027eb324193953567913ab33483ea454d0af566..c628b0219b0faa6e70f494f0b80c3e5178535ced 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -25,117 +25,76 @@ void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo) { // delete any stored version of a SIB after 3 hours // from the moment it was successfully confirmed as valid - if (SInfo->sib1) { + if (SInfo->sib1 && SInfo->sib1_timer >= 0) { SInfo->sib1_timer += 10; - if (SInfo->sib1_timer > 10800000) { - SInfo->sib1_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB1, SInfo->sib1, 1); - SInfo->sib1 = NULL; - } + if (SInfo->sib1_timer > 10800000) + SInfo->sib1_timer = -1; } - if (SInfo->sib2) { + if (SInfo->sib2 && SInfo->sib2_timer >= 0) { SInfo->sib2_timer += 10; - if (SInfo->sib2_timer > 10800000) { - SInfo->sib2_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB2, SInfo->sib2, 1); - SInfo->sib2 = NULL; - } + if (SInfo->sib2_timer > 10800000) + SInfo->sib2_timer = -1; } - if (SInfo->sib3) { + if (SInfo->sib3 && SInfo->sib3_timer >= 0) { SInfo->sib3_timer += 10; - if (SInfo->sib3_timer > 10800000) { - SInfo->sib3_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB3, SInfo->sib3, 1); - SInfo->sib3 = NULL; - } + if (SInfo->sib3_timer > 10800000) + SInfo->sib3_timer = -1; } - if (SInfo->sib4) { + if (SInfo->sib4 && SInfo->sib4_timer >= 0) { SInfo->sib4_timer += 10; - if (SInfo->sib4_timer > 10800000) { - SInfo->sib4_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB4, SInfo->sib4, 1); - SInfo->sib4 = NULL; - } + if (SInfo->sib4_timer > 10800000) + SInfo->sib4_timer = -1; } - if (SInfo->sib5) { + if (SInfo->sib5 && SInfo->sib5_timer >= 0) { SInfo->sib5_timer += 10; - if (SInfo->sib5_timer > 10800000) { - SInfo->sib5_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB5, SInfo->sib5, 1); - SInfo->sib5 = NULL; - } + if (SInfo->sib5_timer > 10800000) + SInfo->sib5_timer = -1; } - if (SInfo->sib6) { + if (SInfo->sib6 && SInfo->sib6_timer >= 0) { SInfo->sib6_timer += 10; - if (SInfo->sib6_timer > 10800000) { - SInfo->sib6_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB6, SInfo->sib6, 1); - SInfo->sib6 = NULL; - } + if (SInfo->sib6_timer > 10800000) + SInfo->sib6_timer = -1; } - if (SInfo->sib7) { + if (SInfo->sib7 && SInfo->sib7_timer >= 0) { SInfo->sib7_timer += 10; - if (SInfo->sib7_timer > 10800000) { - SInfo->sib7_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB7, SInfo->sib7, 1); - SInfo->sib7 = NULL; - } + if (SInfo->sib7_timer > 10800000) + SInfo->sib7_timer = -1; } - if (SInfo->sib8) { + if (SInfo->sib8 && SInfo->sib8_timer >= 0) { SInfo->sib8_timer += 10; - if (SInfo->sib8_timer > 10800000) { - SInfo->sib8_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB8, SInfo->sib8, 1); - SInfo->sib8 = NULL; - } + if (SInfo->sib8_timer > 10800000) + SInfo->sib8_timer = -1; } - if (SInfo->sib9) { + if (SInfo->sib9 && SInfo->sib9_timer >= 0) { SInfo->sib9_timer += 10; - if (SInfo->sib9_timer > 10800000) { - SInfo->sib9_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB9, SInfo->sib9, 1); - SInfo->sib9 = NULL; - } + if (SInfo->sib9_timer > 10800000) + SInfo->sib9_timer = -1; + } - if (SInfo->sib10) { + if (SInfo->sib10 && SInfo->sib10_timer >= 0) { SInfo->sib10_timer += 10; - if (SInfo->sib10_timer > 10800000) { - SInfo->sib10_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB10_r16, SInfo->sib10, 1); - SInfo->sib10 = NULL; - } + if (SInfo->sib10_timer > 10800000) + SInfo->sib10_timer = -1; } - if (SInfo->sib11) { + if (SInfo->sib11 && SInfo->sib11_timer >= 0) { SInfo->sib11_timer += 10; - if (SInfo->sib11_timer > 10800000) { - SInfo->sib11_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB11_r16, SInfo->sib11, 1); - SInfo->sib11 = NULL; - } + if (SInfo->sib11_timer > 10800000) + SInfo->sib11_timer = -1; } - if (SInfo->sib12) { + if (SInfo->sib12 && SInfo->sib12_timer >= 0) { SInfo->sib12_timer += 10; - if (SInfo->sib12_timer > 10800000) { - SInfo->sib12_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB12_r16, SInfo->sib12, 1); - SInfo->sib12 = NULL; - } + if (SInfo->sib12_timer > 10800000) + SInfo->sib12_timer = -1; } - if (SInfo->sib13) { + if (SInfo->sib13 && SInfo->sib13_timer >= 0) { SInfo->sib13_timer += 10; - if (SInfo->sib13_timer > 10800000) { - SInfo->sib13_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB13_r16, SInfo->sib13, 1); - SInfo->sib13 = NULL; - } + if (SInfo->sib13_timer > 10800000) + SInfo->sib13_timer = -1; } - if (SInfo->sib14) { + if (SInfo->sib14 && SInfo->sib14_timer >= 0) { SInfo->sib14_timer += 10; - if (SInfo->sib14_timer > 10800000) { - SInfo->sib14_timer = 0; - SEQUENCE_free(&asn_DEF_NR_SIB14_r16, SInfo->sib14, 1); - SInfo->sib14 = NULL; - } + if (SInfo->sib14_timer > 10800000) + SInfo->sib14_timer = -1; } } diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index d7cc49643946a5a802d640171c60efb6eebf3a87..b1920b652293a177aa583417e8ebe5840e3b786a 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -825,11 +825,47 @@ int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id) { return !GTPNOK; } -// Legacy delete tunnel finish by deleting all the ue id -// so the list of bearer provided is only a design bug int gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { - return newGtpuDeleteAllTunnels(instance, req_pP->rnti); + LOG_D(GTPU, "[%ld] Start delete tunnels for RNTI %x\n", instance, req_pP->rnti); + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst = &globGtp.instances[compatInst(instance)]; + auto ptrRNTI = inst->ue2te_mapping.find(req_pP->rnti); + if (ptrRNTI == inst->ue2te_mapping.end()) { + LOG_W(GTPU, "[%ld] Delete Released GTP tunnels for rnti: %x, but no tunnel exits\n", instance, req_pP->rnti); + pthread_mutex_unlock(&globGtp.gtp_lock); + return -1; + } + + int nb = 0; + + for (int i = 0; i < req_pP->num_erab; i++) { + auto ptr2 = ptrRNTI->second.bearers.find(req_pP->eps_bearer_id[i]); + if (ptr2 == ptrRNTI->second.bearers.end()) { + LOG_E(GTPU, + "[%ld] GTP-U instance: delete of not existing tunnel RNTI:RAB: %x/%x\n", + instance, + req_pP->rnti, + req_pP->eps_bearer_id[i]); + } else { + globGtp.te2ue_mapping.erase(ptr2->second.teid_incoming); + nb++; + } + } + + if (ptrRNTI->second.bearers.size() == 0) + // no tunnels on this rnti, erase the ue entry + inst->ue2te_mapping.erase(ptrRNTI); + + pthread_mutex_unlock(&globGtp.gtp_lock); + LOG_I(GTPU, "[%ld] Deleted released tunnels for RNTI %x (%d tunnels deleted)\n", instance, req_pP->rnti, nb); + return !GTPNOK; +} + +// Legacy delete tunnel finish by deleting all the ue id +int gtpv1u_delete_all_s1u_tunnel(const instance_t instance, const rnti_t rnti) +{ + return newGtpuDeleteAllTunnels(instance, rnti); } int newGtpuDeleteTunnels(instance_t instance, ue_id_t ue_id, int nbTunnels, pdusessionid_t *pdusession_id) { diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index f8228677fc0ff2b0a0d930c7096b6d3fc6a56b94..d57769c5091515c9e64613ff164ed10c760c13ed 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -61,6 +61,7 @@ extern "C" { ); int gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP); + int gtpv1u_delete_all_s1u_tunnel(const instance_t instance, const rnti_t rnti); int gtpv1u_create_x2u_tunnel(const instance_t instanceP, const gtpv1u_enb_create_x2u_tunnel_req_t *const create_tunnel_req_pP,