Merge branch 'integration_2024_w23' into 'develop'
Integration: `2024.w23` See merge request oai/openairinterface5g!2788 * !2510 NR UE MAC UCI on PUSCH and aperiodic CSI reporting * !2597 LTTng logger (CTF) * !2751 synch the USRP time accross devices using the host clock * !2775 Remove some global variables * !2779 remove rb_mask_ul from permanent storage for stack local usage * !2782 USRP: add a T trace to record the RX IQ data on antenna 0 * !2783 build_oai: fix bad options' names * !2753 Pucch power control
This commit is contained in:
@@ -284,6 +284,7 @@ add_boolean_option(DEBUG_ASN1 False "Enable ASN1 debug logs" OFF)
|
||||
# see common/utils/config.h
|
||||
add_boolean_option(TRACE_ASN1C_ENC_DEC OFF "Enable ASN1 encoder/decoder debug traces via OAI logging system" ON)
|
||||
add_boolean_option(T_TRACER True "Activate the T tracer, a debugging/monitoring framework" ON)
|
||||
add_boolean_option(ENABLE_LTTNG False "Activate the LTTNG tracer, a debugging/monitoring framework" ON)
|
||||
add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs" ON)
|
||||
add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace" ON)
|
||||
add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace" ON)
|
||||
@@ -659,6 +660,14 @@ add_library(UTIL
|
||||
${OPENAIR_DIR}/common/utils/time_meas.c
|
||||
${OPENAIR_DIR}/common/utils/time_stat.c
|
||||
)
|
||||
if (ENABLE_LTTNG)
|
||||
find_package(LTTngUST 2.3.8 EXACT REQUIRED)
|
||||
target_sources(UTIL PRIVATE common/utils/LOG/lttng-tp.c)
|
||||
target_link_libraries(UTIL PUBLIC lttng-ust)
|
||||
else()
|
||||
message(STATUS "LTTNG support disabled")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(cap libcap)
|
||||
if (cap_FOUND)
|
||||
# see system.c for more info
|
||||
|
||||
+15
-4
@@ -124,6 +124,8 @@ Options:
|
||||
--disable-cpu-affinity
|
||||
Disables CPU Affinity between UHD/TX/RX Threads (Valid only when deadline scheduler is disabled). By defaulT, CPU Affinity is enabled when not using deadline scheduler. It is enabled only with >2 CPUs. For eNB, CPU_0-> Device library (UHD), CPU_1->TX Threads, CPU_2...CPU_MAX->Rx Threads. For UE, CPU_0->Device Library(UHD), CPU_1..CPU_MAX -> All the UE threads
|
||||
--enable-cpu-affinity
|
||||
--enable-LTTNG
|
||||
Enable LTTNG log. While lttng is enabled, T-Tracer will be disabled
|
||||
--disable-T-Tracer
|
||||
Disables the T tracer.
|
||||
--disable-hardware-dependency
|
||||
@@ -353,6 +355,11 @@ function main() {
|
||||
BUILD_DOXYGEN=1
|
||||
echo_info "Will build doxygen support"
|
||||
shift;;
|
||||
--enable-LTTNG)
|
||||
CMAKE_CMD="$CMAKE_CMD -DENABLE_LTTNG=ON -DT_TRACER=OFF"
|
||||
echo_info "Enable LTTNG tracer"
|
||||
USE_LTTNG=1
|
||||
shift 1;;
|
||||
--disable-T-Tracer)
|
||||
CMAKE_CMD="$CMAKE_CMD -DT_TRACER=False"
|
||||
echo_info "Disabling the T tracer"
|
||||
@@ -414,19 +421,19 @@ function main() {
|
||||
grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt"
|
||||
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True"
|
||||
shift;;
|
||||
--sanitize-undefined | -fundefined=address)
|
||||
--sanitize-undefined | -fsanitize=undefined)
|
||||
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_UNDEFINED=True"
|
||||
shift;;
|
||||
--sanitize-memory | -fsanitize=memory)
|
||||
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_MEMORY=ON -DSANITIZE_ADDRESS=OFF -DSANITIZE_UNDEFINED=OFF"
|
||||
shift;;
|
||||
--sanitize-thread | -fsanitize=thread)
|
||||
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_THREAD=True"
|
||||
shift;;
|
||||
--trace-asn1c-enc-dec)
|
||||
CMAKE_CMD="$CMAKE_CMD -DTRACE_ASN1C_ENC_DEC=ON"
|
||||
echo_info "Enabling asn1c internal traces via OAI logging system"
|
||||
shift 1;;
|
||||
--sanitize-thread | -fthread=address)
|
||||
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_THREAD=True"
|
||||
shift;;
|
||||
-h | --help)
|
||||
print_help
|
||||
exit 1;;
|
||||
@@ -454,6 +461,10 @@ function main() {
|
||||
if [ "$INSTALL_EXTERNAL" = "1" ] ; then
|
||||
echo_info "Installing packages"
|
||||
check_install_oai_software
|
||||
if [ "$USE_LTTNG" = "1" ] ; then
|
||||
echo_info "installing LTTng"
|
||||
install_lttng $1
|
||||
fi
|
||||
if [ "$HW" == "OAI_USRP" ] ; then
|
||||
echo_info "installing packages for USRP support"
|
||||
check_install_usrp_uhd_driver
|
||||
|
||||
@@ -704,6 +704,97 @@ install_simde_from_source(){
|
||||
$SUDO \cp -rv ../simde /usr/include
|
||||
}
|
||||
|
||||
install_lttng() {
|
||||
if [[ "$OS_DISTRO" != "ubuntu" ]]; then
|
||||
echo_info "LTTng is supported only for ubuntu at the moment."
|
||||
echo_info $distribution
|
||||
return
|
||||
fi
|
||||
|
||||
set +e
|
||||
$SUDO apt-add-repository ppa:lttng/stable-2.13 -y && apt-get update
|
||||
$SUDO apt-get install -y lttng-tools lttng-modules-dkms liblttng-ust-dev
|
||||
if [[ $? > 0 ]]; then
|
||||
echo "Failed to install LTTng using apt. Installing from source"
|
||||
install_lttng_deps
|
||||
install_lttng_from_source
|
||||
fi
|
||||
set -e
|
||||
}
|
||||
|
||||
install_lttng_deps() {
|
||||
echo "installing dependencies of LTTng"
|
||||
$SUDO apt-get install uuid-dev libxml2-dev -y
|
||||
}
|
||||
|
||||
install_lttng_from_source() {
|
||||
echo "installing LTTng from source"
|
||||
install_popt_1_18_from_source
|
||||
install_userspace_rcu
|
||||
install_lttng_ust_2_13_from_source
|
||||
install_lttng_tools_2_13_from_source
|
||||
}
|
||||
|
||||
install_popt_1_18_from_source() {
|
||||
$SUDO $INSTALLER -y install wget
|
||||
echo_info "\nInstalling popt_1_18."
|
||||
cd $(mktemp -d) &&
|
||||
wget http://ftp.rpm.org/popt/releases/popt-1.x/popt-1.18.tar.gz
|
||||
tar -xf popt-1.18.tar.gz && cd popt-1.18
|
||||
./configure && make -j16 && $SUDO make install
|
||||
}
|
||||
|
||||
install_userspace_rcu() {
|
||||
echo_info "\nInstalling U-RCU from source."
|
||||
cd /tmp
|
||||
$SUDO rm -rf /tmp/urcu
|
||||
git clone https://github.com/urcu/userspace-rcu.git /tmp/urcu
|
||||
cd /tmp/urcu
|
||||
git checkout stable-0.12
|
||||
./bootstrap && ./configure && make
|
||||
$SUDO make install
|
||||
$SUDO ldconfig
|
||||
}
|
||||
|
||||
|
||||
install_lttng_modules_2_13_from_source() {
|
||||
$SUDO $INSTALLER -y install wget
|
||||
echo_info "\nInstalling LTTng Modules."
|
||||
cd $(mktemp -d) &&
|
||||
wget https://lttng.org/files/lttng-modules/lttng-modules-latest-2.13.tar.bz2 &&
|
||||
tar -xf lttng-modules-latest-2.13.tar.bz2 &&
|
||||
cd lttng-modules-2.13.* &&
|
||||
make &&
|
||||
$SUDO make modules_install &&
|
||||
$SUDO depmod -a
|
||||
}
|
||||
|
||||
install_lttng_ust_2_13_from_source() {
|
||||
$SUDO $INSTALLER -y install wget
|
||||
echo_info "\nInstalling LTTng UST."
|
||||
cd $(mktemp -d) &&
|
||||
wget https://lttng.org/files/lttng-ust/lttng-ust-latest-2.13.tar.bz2 &&
|
||||
tar -xf lttng-ust-latest-2.13.tar.bz2 &&
|
||||
cd lttng-ust-2.13.* &&
|
||||
./configure --disable-numa &&
|
||||
make &&
|
||||
$SUDO make install &&
|
||||
$SUDO ldconfig
|
||||
}
|
||||
|
||||
install_lttng_tools_2_13_from_source() {
|
||||
$SUDO $INSTALLER -y install wget
|
||||
echo_info "\nInstalling LTTng Tools."
|
||||
cd $(mktemp -d) &&
|
||||
wget https://lttng.org/files/lttng-tools/lttng-tools-latest-2.13.tar.bz2 &&
|
||||
tar -xf lttng-tools-latest-2.13.tar.bz2 &&
|
||||
cd lttng-tools-2.13.* &&
|
||||
./configure &&
|
||||
make &&
|
||||
$SUDO make install &&
|
||||
$SUDO ldconfig
|
||||
}
|
||||
|
||||
#################################################
|
||||
# 2. compile
|
||||
################################################
|
||||
|
||||
@@ -15,5 +15,6 @@ By default, this facility is included at build-time and activated at run-time. T
|
||||
* [runtime usage](rtusage.md)
|
||||
* [developer usage](devusage.md)
|
||||
* [module architecture](arch.md)
|
||||
* [lttng usage](lttng_logs.md)
|
||||
|
||||
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
# OAI gNB LTTng Tracing Setup Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide will walk you through setting up tracing for an OpenAirInterface (OAI) gNB (gNodeB) using LTTng (Linux Trace Toolkit Next Generation) and Babeltrace.
|
||||
### What is LTTng and Why Use It?
|
||||
|
||||
LTTng, or Linux Trace Toolkit Next Generation, is a powerful logging framework designed for Linux systems. It provides low-overhead tracing capabilities, allowing developers to monitor and analyze system behavior in real-time without significant performance impact. LTTng offers several advantages:
|
||||
|
||||
- **Low Overhead**: LTTng introduces minimal overhead to the system, making it suitable for use in production environments without affecting system performance.
|
||||
|
||||
- **Customizable**: LTTng allows users to define custom tracepoints in their applications, providing fine-grained control over what events to trace and collect.
|
||||
|
||||
- **Scalability**: It can scale to large distributed systems, making it suitable for tracing complex software stacks across multiple nodes.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Ubuntu system
|
||||
|
||||
Note: only LTTng 2.3.8 is supported.
|
||||
|
||||
## Building OAI gNB
|
||||
|
||||
1. **Clean and Build OAI gNB with LTTng:**
|
||||
|
||||
1.1 Install Dependencies
|
||||
|
||||
```bash
|
||||
./build_oai --ninja -I --clean --enable-LTTNG
|
||||
|
||||
```
|
||||
1.2 Build gNB and nrUE
|
||||
```
|
||||
./build_oai --ninja --gNB --nrUE -w SIMU --enable-LTTNG
|
||||
```
|
||||
## Setting up LTTng
|
||||
|
||||
1. **Start LTTng Session and Relay:**
|
||||
|
||||
```bash
|
||||
sudo lttng-sessiond -d
|
||||
sudo lttng-relayd -d
|
||||
```
|
||||
|
||||
2. **Create Live LTTng Session:**
|
||||
|
||||
```bash
|
||||
sudo lttng create my-session --live --set-url=net://127.0.0.1
|
||||
```
|
||||
|
||||
3. **Enable gNB Trace Events:**
|
||||
|
||||
```bash
|
||||
sudo lttng enable-event --userspace OAI:gNB
|
||||
```
|
||||
|
||||
4. **Start LTTng Tracing:**
|
||||
|
||||
```bash
|
||||
sudo lttng start
|
||||
```
|
||||
|
||||
## Running the gNB
|
||||
|
||||
1. **Run gNB:**
|
||||
|
||||
```bash
|
||||
./$binary_path -O $configuration_file PARALLEL_SINGLE_THREAD --rfsimulator.serveraddr server --rfsim --sa -E
|
||||
```
|
||||
|
||||
## Verifying Tracepoints
|
||||
|
||||
1. **List Active Tracepoints:**
|
||||
|
||||
```bash
|
||||
sudo lttng list -u
|
||||
```
|
||||
|
||||
*Possible Output:*
|
||||
|
||||
```
|
||||
UST events:
|
||||
-------------
|
||||
|
||||
PID: 1154722 - Name: /home/firecell/Desktop/FirecellRepos/firecellrd-oai5g-ran/cmake_targets/ran_build/build/nr-softmodem
|
||||
OAI:gNB (loglevel: TRACE_DEBUG_FUNCTION (12)) (type: tracepoint)
|
||||
```
|
||||
|
||||
## Analyzing Traces
|
||||
|
||||
1. **Install Babeltrace:**
|
||||
|
||||
```bash
|
||||
sudo apt-get install babeltrace
|
||||
```
|
||||
|
||||
|
||||
2. **Capture Trace Logs Live:**
|
||||
|
||||
- To learn the full path of the trace session:
|
||||
|
||||
```bash
|
||||
babeltrace --input-format=lttng-live net://localhost
|
||||
```
|
||||
|
||||
- Trace logs using the full path:
|
||||
|
||||
```bash
|
||||
babeltrace --input-format=lttng-live net://localhost/host/firecell-XPS-15-9530/my-session
|
||||
```
|
||||
|
||||
*Possible Output:*
|
||||
|
||||
```
|
||||
[19:35:32.181608002] (+2.664882127) firecell-XPS-15-9530 OAI:gNB: { cpu_id = 10 }, { MODNAME = "OAI-NR_MAC info", EVENTID = -1, SFN = -1, SLOT = -1, FUNCTION = "gNB_dlsch_ulsch_scheduler", LINE = 246, MSG = "Frame.Slot 0.0\n" }
|
||||
```
|
||||
3. **Capture Trace Logs Offline:**
|
||||
|
||||
- Create an offline trace session with a specified output directory:
|
||||
|
||||
```bash
|
||||
sudo lttng create offline_session --output=/home/trace_offline/
|
||||
```
|
||||
|
||||
- Enable gNB trace events:
|
||||
|
||||
```bash
|
||||
sudo lttng enable-event --userspace OAI:gNB
|
||||
```
|
||||
|
||||
- Start capturing trace logs:
|
||||
|
||||
```bash
|
||||
sudo lttng start
|
||||
```
|
||||
|
||||
- Stop the trace capture:
|
||||
|
||||
```bash
|
||||
sudo lttng stop
|
||||
```
|
||||
|
||||
- Destroy the trace session:
|
||||
|
||||
```bash
|
||||
sudo lttng destroy
|
||||
```
|
||||
|
||||
- Use Babeltrace to analyze the captured trace logs:
|
||||
|
||||
```bash
|
||||
sudo babeltrace /home/trace_offline/
|
||||
```
|
||||
@@ -603,6 +603,25 @@ void logRecord_mt(const char *file,
|
||||
log_output_memory(c, file,func,line,comp,level,format,args);
|
||||
va_end(args);
|
||||
}
|
||||
#if ENABLE_LTTNG
|
||||
void logRecord_lttng(const char *file, const char *func, int line, int comp, int level, const char *format, ...)
|
||||
{
|
||||
log_component_t *c = &g_log->log_component[comp];
|
||||
char header[48];
|
||||
char buf[MAX_LOG_TOTAL];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(buf, sizeof(buf) - 1, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (map_int_to_str(log_level_names, level) != NULL)
|
||||
snprintf(header, sizeof(header), "OAI-%s %s", c->name, map_int_to_str(log_level_names, level));
|
||||
else
|
||||
snprintf(header, sizeof(header), "OAI-%s", c->name);
|
||||
|
||||
LOG_FC(header, func, line, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
void vlogRecord_mt(const char *file,
|
||||
const char *func,
|
||||
|
||||
+52
-3
@@ -52,6 +52,9 @@
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <common/utils/utils.h>
|
||||
#if ENABLE_LTTNG
|
||||
#include "lttng-log.h"
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#include <assert.h>
|
||||
#ifdef NDEBUG
|
||||
@@ -234,6 +237,10 @@ void logTerm (void);
|
||||
int isLogInitDone (void);
|
||||
void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
|
||||
void vlogRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, va_list args );
|
||||
#if ENABLE_LTTNG
|
||||
void logRecord_lttng(const char *file, const char *func, int line, int comp, int level, const char *format, ...)
|
||||
__attribute__((format(printf, 6, 7)));
|
||||
#endif
|
||||
void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... );
|
||||
int set_log(int component, int level);
|
||||
void set_glog(int level);
|
||||
@@ -425,9 +432,50 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
||||
|
||||
/* define variable only used in LOG macro's */
|
||||
#define LOG_VAR(A, B) A B
|
||||
|
||||
#else /* no T_TRACER */
|
||||
|
||||
#else /* T_TRACER */
|
||||
#if ENABLE_LTTNG
|
||||
#define LOG_E(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_ERR) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ERR, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_W(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_WARNING) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_WARNING, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_A(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_ANALYSIS) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ANALYSIS, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_I(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_INFO) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_INFO, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_D(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_DEBUG) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_DEBUG, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_T(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_TRACE) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_TRACE, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_DDUMP(c, b, s, f, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_DEBUG) \
|
||||
log_dump(c, b, s, f, x); \
|
||||
} while (0)
|
||||
#else
|
||||
#define LOG_E(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_ERR) \
|
||||
@@ -469,6 +517,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
||||
if (g_log->log_component[c].level >= OAILOG_TRACE) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_TRACE, x); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define VLOG(c, l, f, args) \
|
||||
do { \
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file lttng-log.h
|
||||
* \brief LTTng Log interface
|
||||
* \author Anurag Asokan
|
||||
* \date 2024
|
||||
* \version 0.5
|
||||
* @ingroup util
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __LTTNG_LOG_H__
|
||||
#define __LTTNG_LOG_H__
|
||||
#if ENABLE_LTTNG
|
||||
#include "lttng-tp.h"
|
||||
|
||||
#define LOG_FC(component, func, line, log) \
|
||||
do { \
|
||||
tracepoint(OAI, gNB, component, -1, -1, -1, func, line, log); \
|
||||
} while (0)
|
||||
#else
|
||||
#define LOG_FC(component, func, line, log)
|
||||
#endif
|
||||
|
||||
#endif /** __LTTNG_LOG_H__ */
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file lttng-tp.c
|
||||
* \brief Lttng trace implementaion
|
||||
* \author Anurag Asokan
|
||||
* \date 2024
|
||||
* \version 0.5
|
||||
* @ingroup util
|
||||
|
||||
*/
|
||||
//This file is used to define the tracepoints for the lttng tracing.In order to to do linkage with the lttng-tp.h file, we need to define the tracepoints here.
|
||||
#define TRACEPOINT_CREATE_PROBES
|
||||
#define TRACEPOINT_DEFINE
|
||||
|
||||
#include "lttng-tp.h"
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file lttng-tp.h
|
||||
* \brief Lttng tracer implementaion
|
||||
* \author Anurag Asokan
|
||||
* \date 2024
|
||||
* \version 0.5
|
||||
* @ingroup util
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _LTTNG_TP_H
|
||||
#define _LTTNG_TP_H
|
||||
|
||||
#undef TRACEPOINT_PROVIDER
|
||||
#define TRACEPOINT_PROVIDER OAI
|
||||
|
||||
#undef TRACEPOINT_INCLUDE
|
||||
#define TRACEPOINT_INCLUDE "./common/utils/LOG/lttng-tp.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <lttng/tracepoint.h>
|
||||
|
||||
TRACEPOINT_EVENT(
|
||||
OAI,
|
||||
gNB,
|
||||
TP_ARGS(const char*, log_modName, int, event_id, int, sfn, int, slot, const char*, funcName, int, lineNo, const char*, msg),
|
||||
TP_FIELDS(ctf_string(MODNAME, log_modName) ctf_integer(int32_t, EVENTID, event_id) ctf_integer(int32_t, SFN, sfn)
|
||||
ctf_integer(int32_t, SLOT, slot) ctf_string(FUNCTION, funcName) ctf_integer(int32_t, LINE, lineNo)
|
||||
ctf_string(MSG, msg)))
|
||||
TRACEPOINT_LOGLEVEL(OAI, gNB, TRACE_DEBUG_FUNCTION)
|
||||
|
||||
#endif /* _LTTNG_TP_H */
|
||||
|
||||
#include <lttng/tracepoint-event.h>
|
||||
@@ -4,6 +4,11 @@ ID = ENB_MASTER_TICK
|
||||
GROUP = ALL:GENERAL:ENB
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe
|
||||
|
||||
ID = USRP_RX_ANT0
|
||||
DESC = RX IQ data as received by USRP driver on antenna 0
|
||||
GROUP = ALL:HEAVY
|
||||
FORMAT = int,timestap : buffer,data
|
||||
|
||||
#PHY logs
|
||||
ID = ENB_PHY_UL_TICK
|
||||
DESC = eNodeB uplink tick - one tick per ms at start of uplink processing
|
||||
|
||||
@@ -37,18 +37,6 @@
|
||||
typedef signed char int8_t;
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t uci_format;
|
||||
uint8_t uci_channel;
|
||||
uint8_t harq_ack_bits;
|
||||
uint32_t harq_ack;
|
||||
uint8_t csi_bits;
|
||||
uint32_t csi;
|
||||
uint8_t sr_bits;
|
||||
uint32_t sr;
|
||||
} fapi_nr_uci_pdu_rel15_t;
|
||||
|
||||
typedef enum {
|
||||
RLM_no_monitoring = 0,
|
||||
RLM_out_of_sync = 1,
|
||||
@@ -257,10 +245,16 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// payloads with fixed array size
|
||||
// no place to free the dinamically allocated
|
||||
// vector without L1 implementation
|
||||
uint16_t harq_ack_bit_length;
|
||||
uint64_t harq_payload;
|
||||
uint16_t csi_part1_bit_length;
|
||||
uint64_t csi_part1_payload;
|
||||
uint16_t csi_part2_bit_length;
|
||||
uint8_t alpha_scaling;
|
||||
uint64_t csi_part2_payload;
|
||||
uint8_t alpha_scaling; // 0 = 0.5, 1 = 0.65, 2 = 0.8, 3 = 1
|
||||
uint8_t beta_offset_harq_ack;
|
||||
uint8_t beta_offset_csi1;
|
||||
uint8_t beta_offset_csi2;
|
||||
@@ -355,6 +349,7 @@ typedef struct
|
||||
uint8_t nr_of_symbols;
|
||||
uint32_t tbslbrm;
|
||||
uint8_t ldpcBaseGraph;
|
||||
uint8_t ulsch_indicator;
|
||||
//Optional Data only included if indicated in pduBitmap
|
||||
nfapi_nr_ue_pusch_data_t pusch_data;
|
||||
nfapi_nr_ue_pusch_uci_t pusch_uci;
|
||||
|
||||
@@ -114,10 +114,8 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb) {
|
||||
|
||||
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9])
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
NR_gNB_COMMON *common_vars = &gNB->common_vars;
|
||||
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
|
||||
@@ -140,8 +138,8 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb
|
||||
for (int s=first_symb;s<(first_symb+num_symb);s++) {
|
||||
int offset0 = ((slot&3)*frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
|
||||
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
|
||||
if ((gNB->rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe
|
||||
!(I0_SKIP_DC && rb == frame_parms->N_RB_UL>>1)) { // skip middle PRB because of artificial noise possibly created by FFT
|
||||
if ((rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe
|
||||
!(I0_SKIP_DC && rb == frame_parms->N_RB_UL >> 1)) { // skip middle PRB because of artificial noise possibly created by FFT
|
||||
int offset = offset0 + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
|
||||
nb_symb[rb]++;
|
||||
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
@@ -192,7 +190,6 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Scope: This function computes the UL SNR from the UL channel estimates
|
||||
//
|
||||
// Todo:
|
||||
|
||||
@@ -54,7 +54,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
|
||||
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
|
||||
|
||||
void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot,int first_symb,int num_symb);
|
||||
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]);
|
||||
|
||||
void nr_gnb_measurements(PHY_VARS_gNB *gNB,
|
||||
NR_gNB_ULSCH_t *ulsch,
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
|
||||
//#define DEBUG_LLR_SIC
|
||||
|
||||
int16_t nr_zeros[8] __attribute__((aligned(16))) = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
//==============================================================================================
|
||||
// SINGLE-STREAM
|
||||
//==============================================================================================
|
||||
|
||||
@@ -123,6 +123,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch_ue->pusch_pdu;
|
||||
|
||||
uint32_t tb_size = pusch_pdu->pusch_data.tb_size;
|
||||
AssertFatal(pusch_pdu->pusch_uci.harq_ack_bit_length == 0 &&
|
||||
pusch_pdu->pusch_uci.csi_part1_bit_length == 0 &&
|
||||
pusch_pdu->pusch_uci.csi_part2_bit_length == 0,
|
||||
"UCI on PUSCH not supported at PHY\n");
|
||||
|
||||
int start_symbol = pusch_pdu->start_symbol_index;
|
||||
uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
|
||||
uint8_t number_of_symbols = pusch_pdu->nr_of_symbols;
|
||||
|
||||
@@ -622,9 +622,6 @@ typedef struct PHY_VARS_gNB_s {
|
||||
/// PUSCH DMRS
|
||||
uint32_t ****nr_gold_pusch_dmrs;
|
||||
|
||||
// Mask of occupied RBs, per symbol and PRB
|
||||
uint32_t rb_mask_ul[14][9];
|
||||
|
||||
/// PRS sequence
|
||||
uint32_t ****nr_gold_prs;
|
||||
|
||||
|
||||
@@ -541,20 +541,20 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
|
||||
}
|
||||
|
||||
// Function to fill UL RB mask to be used for N0 measurements
|
||||
void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
|
||||
static void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, uint32_t rb_mask_ul[14][9])
|
||||
{
|
||||
int rb = 0;
|
||||
int rb2 = 0;
|
||||
int prbpos = 0;
|
||||
|
||||
for (int symbol = 0; symbol < 14; symbol++) {
|
||||
for (int m = 0; m < 9; m++) {
|
||||
gNB->rb_mask_ul[symbol][m] = 0;
|
||||
rb_mask_ul[symbol][m] = 0;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
prbpos = (m * 32) + i;
|
||||
if (prbpos>gNB->frame_parms.N_RB_UL)
|
||||
break;
|
||||
gNB->rb_mask_ul[symbol][m] |= (gNB->ulprbbl[prbpos] > 0 ? 1U : 0) << i;
|
||||
rb_mask_ul[symbol][m] |= (gNB->ulprbbl[prbpos] > 0 ? 1U : 0) << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -574,7 +574,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
rb2 = rb + pucch_pdu->bwp_start +
|
||||
((symbol < pucch_pdu->start_symbol_index+(pucch_pdu->nr_of_symbols>>1)) || (pucch_pdu->freq_hop_flag == 0) ?
|
||||
pucch_pdu->prb_start : pucch_pdu->second_hop_prb);
|
||||
gNB->rb_mask_ul[symbol][rb2>>5] |= (((uint32_t)1)<<(rb2&31));
|
||||
rb_mask_ul[symbol][rb2>>5] |= (((uint32_t)1)<<(rb2&31));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -599,7 +599,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
LOG_D(PHY, "symbol %d Filling rb_mask_ul rb_size %d\n", symbol, ulsch_harq->ulsch_pdu.rb_size);
|
||||
for (rb = 0; rb < ulsch_harq->ulsch_pdu.rb_size; rb++) {
|
||||
rb2 = rb + ulsch_harq->ulsch_pdu.rb_start + ulsch_harq->ulsch_pdu.bwp_start;
|
||||
gNB->rb_mask_ul[symbol][rb2 >> 5] |= 1U << (rb2 & 31);
|
||||
rb_mask_ul[symbol][rb2 >> 5] |= 1U << (rb2 & 31);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -613,14 +613,13 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
|
||||
for(int symbol = 0; symbol<(1<<srs_pdu->num_symbols); symbol++) {
|
||||
for(rb = srs_pdu->bwp_start; rb < (srs_pdu->bwp_start+srs_pdu->bwp_size); rb++) {
|
||||
gNB->rb_mask_ul[gNB->frame_parms.symbols_per_slot - srs_pdu->time_start_position - 1 + symbol][rb >> 5] |= 1U
|
||||
rb_mask_ul[gNB->frame_parms.symbols_per_slot - srs_pdu->time_start_position - 1 + symbol][rb >> 5] |= 1U
|
||||
<< (rb & 31);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int fill_srs_reported_symbol_list(nfapi_nr_srs_reported_symbol_t *prgs,
|
||||
@@ -718,8 +717,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
|
||||
LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
|
||||
|
||||
fill_ul_rb_mask(gNB, frame_rx, slot_rx);
|
||||
// Mask of occupied RBs, per symbol and PRB
|
||||
uint32_t rb_mask_ul[14][9];
|
||||
fill_ul_rb_mask(gNB, frame_rx, slot_rx, rb_mask_ul);
|
||||
|
||||
int first_symb=0,num_symb=0;
|
||||
if (gNB->frame_parms.frame_type == TDD)
|
||||
@@ -731,7 +731,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
}
|
||||
else
|
||||
num_symb = NR_NUMBER_OF_SYMBOLS_PER_SLOT;
|
||||
gNB_I0_measurements(gNB,slot_rx,first_symb,num_symb);
|
||||
gNB_I0_measurements(gNB, slot_rx, first_symb, num_symb, rb_mask_ul);
|
||||
|
||||
const int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size;
|
||||
int offset = 10 * gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset;
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
||||
#include "phy_frame_config_nr.h"
|
||||
|
||||
void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
|
||||
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp);
|
||||
void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, int frame_tx, int slot_tx, int do_meas);
|
||||
int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
|
||||
|
||||
@@ -186,22 +186,3 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
||||
pucch_vars->active[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
int dummy_csi_status = 0;
|
||||
uint32_t dummy_csi_payload = 0;
|
||||
|
||||
|
||||
/* FFS TODO_NR code that should be removed */
|
||||
|
||||
void set_csi_nr(int csi_status, uint32_t csi_payload)
|
||||
{
|
||||
dummy_csi_status = csi_status;
|
||||
|
||||
if (dummy_csi_status == 0) {
|
||||
dummy_csi_payload = 0;
|
||||
}
|
||||
else {
|
||||
dummy_csi_payload = csi_payload;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,4 @@
|
||||
|
||||
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txdataF);
|
||||
|
||||
void set_csi_nr(int csi_status, uint32_t csi_payload);
|
||||
|
||||
#endif /* PUCCH_UCI_UE_NR_H */
|
||||
|
||||
@@ -629,16 +629,17 @@ int main(int argc, char **argv)
|
||||
12);
|
||||
|
||||
// set UL mask for pucch allocation
|
||||
uint32_t rb_mask_ul[14][9] = {0};
|
||||
for (int s=0;s<frame_parms->symbols_per_slot;s++){
|
||||
if (s>=startingSymbolIndex && s<(startingSymbolIndex+nrofSymbols))
|
||||
for (int rb=0; rb<N_RB; rb++) {
|
||||
int rb2 = rb+startingPRB;
|
||||
gNB->rb_mask_ul[s][rb2>>5] |= (1<<(rb2&31));
|
||||
rb_mask_ul[s][rb2 >> 5] |= (1 << (rb2 & 31));
|
||||
}
|
||||
}
|
||||
|
||||
// noise measurement (all PRBs)
|
||||
gNB_I0_measurements(gNB, nr_slot_tx, 0, gNB->frame_parms.symbols_per_slot);
|
||||
gNB_I0_measurements(gNB, nr_slot_tx, 0, gNB->frame_parms.symbols_per_slot, rb_mask_ul);
|
||||
|
||||
if (n_trials==1) printf("noise rxlev %d (%d dB), rxlev pucch %d dB sigma2 %f dB, SNR %f, TX %f, I0 (pucch) %d, I0 (avg) %d\n",rxlev,dB_fixed(rxlev),dB_fixed(rxlev_pucch),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12),gNB->measurements.n0_subband_power_tot_dB[startingPRB],gNB->measurements.n0_subband_power_avg_dB);
|
||||
if(format==0){
|
||||
|
||||
@@ -1074,8 +1074,6 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc)
|
||||
|
||||
ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = NR_MAX_DLSCH_HARQ_PROCESSES;
|
||||
|
||||
set_csi_nr( 4, 0x0E );
|
||||
|
||||
printf("\n => Test : PUCCH format from dedicated config with CSI alone \n");
|
||||
|
||||
if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) {
|
||||
|
||||
@@ -501,6 +501,7 @@ typedef struct{
|
||||
} CSI_Meas_bitlen_t;
|
||||
|
||||
typedef struct nr_csi_report {
|
||||
NR_CSI_ReportConfigId_t reportConfigId;
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||
long periodicity;
|
||||
uint16_t offset;
|
||||
@@ -561,6 +562,7 @@ typedef struct NR_UE_UL_BWP {
|
||||
NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList_Common;
|
||||
NR_ConfiguredGrantConfig_t *configuredGrantConfig;
|
||||
NR_PUSCH_Config_t *pusch_Config;
|
||||
NR_UCI_OnPUSCH_t *uci_onPusch;
|
||||
NR_PUCCH_Config_t *pucch_Config;
|
||||
NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon;
|
||||
NR_SRS_Config_t *srs_Config;
|
||||
|
||||
@@ -5018,7 +5018,8 @@ void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
}
|
||||
|
||||
//!TODO : same function can be written to handle csi_resources
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template) {
|
||||
void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template)
|
||||
{
|
||||
uint8_t csi_report_id = 0;
|
||||
uint8_t nb_resources = 0;
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||
@@ -5027,7 +5028,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *cs
|
||||
|
||||
// for each CSI measurement report configuration (list of CSI-ReportConfig)
|
||||
LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count);
|
||||
for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||
for (csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++) {
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||
// MAC structure for CSI measurement reports (per UE and per report)
|
||||
nr_csi_report_t *csi_report = &csi_report_template[csi_report_id];
|
||||
@@ -5039,7 +5040,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *cs
|
||||
int csi_resourceidx = 0;
|
||||
while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) {
|
||||
csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||
if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId)
|
||||
if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId)
|
||||
found_resource = 1;
|
||||
csi_resourceidx++;
|
||||
}
|
||||
@@ -5050,6 +5051,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *cs
|
||||
|
||||
reportQuantity_type = csi_reportconfig->reportQuantity.present;
|
||||
csi_report->reportQuantity_type = reportQuantity_type;
|
||||
csi_report->reportConfigId = csi_reportconfig->reportConfigId;
|
||||
|
||||
// setting the CSI or SSB index list
|
||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) {
|
||||
@@ -5114,21 +5116,21 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *cs
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id) {
|
||||
|
||||
uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report)
|
||||
{
|
||||
uint16_t csi_bitlen = 0;
|
||||
uint16_t max_bitlen = 0;
|
||||
L1_RSRP_bitlen_t *CSI_report_bitlen = NULL;
|
||||
CSI_Meas_bitlen_t *csi_meas_bitlen = NULL;
|
||||
|
||||
if (csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP ||
|
||||
csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) {
|
||||
CSI_report_bitlen = &(csi_report_template[csi_report_id].CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
if (csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP ||
|
||||
csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) {
|
||||
CSI_report_bitlen = &(csi_report->CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
csi_bitlen += ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
|
||||
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
|
||||
(CSI_report_bitlen->nb_ssbri_cri -1 )));
|
||||
} else {
|
||||
csi_meas_bitlen = &(csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
csi_meas_bitlen = &(csi_report->csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
uint16_t temp_bitlen;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
temp_bitlen = (csi_meas_bitlen->cri_bitlen+
|
||||
@@ -5142,7 +5144,6 @@ uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_rep
|
||||
}
|
||||
csi_bitlen += max_bitlen;
|
||||
}
|
||||
|
||||
return csi_bitlen;
|
||||
}
|
||||
|
||||
|
||||
@@ -307,9 +307,9 @@ void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report);
|
||||
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template);
|
||||
void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template);
|
||||
|
||||
uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id);
|
||||
uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report);
|
||||
|
||||
uint16_t compute_PDU_length(uint32_t num_TLV, uint16_t total_length);
|
||||
|
||||
|
||||
@@ -952,13 +952,15 @@ static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *targ
|
||||
if (source->uci_OnPUSCH->present == NR_SetupRelease_UCI_OnPUSCH_PR_release)
|
||||
asn1cFreeStruc(asn_DEF_NR_UCI_OnPUSCH, target->uci_OnPUSCH);
|
||||
if (source->uci_OnPUSCH->present == NR_SetupRelease_UCI_OnPUSCH_PR_setup) {
|
||||
if (target->uci_OnPUSCH) {
|
||||
target->uci_OnPUSCH->choice.setup->scaling = source->uci_OnPUSCH->choice.setup->scaling;
|
||||
if (source->uci_OnPUSCH->choice.setup->betaOffsets)
|
||||
UPDATE_IE(target->uci_OnPUSCH->choice.setup->betaOffsets,
|
||||
source->uci_OnPUSCH->choice.setup->betaOffsets,
|
||||
struct NR_UCI_OnPUSCH__betaOffsets);
|
||||
if (!target->uci_OnPUSCH) {
|
||||
target->uci_OnPUSCH = calloc(1, sizeof(*target->uci_OnPUSCH));
|
||||
target->uci_OnPUSCH->choice.setup = calloc(1, sizeof(*target->uci_OnPUSCH->choice.setup));
|
||||
}
|
||||
target->uci_OnPUSCH->choice.setup->scaling = source->uci_OnPUSCH->choice.setup->scaling;
|
||||
if (source->uci_OnPUSCH->choice.setup->betaOffsets)
|
||||
UPDATE_IE(target->uci_OnPUSCH->choice.setup->betaOffsets,
|
||||
source->uci_OnPUSCH->choice.setup->betaOffsets,
|
||||
struct NR_UCI_OnPUSCH__betaOffsets);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1829,143 +1831,153 @@ static void configure_csiim_resource(NR_CSI_IM_Resource_t *target, NR_CSI_IM_Res
|
||||
UPDATE_IE(target->periodicityAndOffset, source->periodicityAndOffset, NR_CSI_ResourcePeriodicityAndOffset_t);
|
||||
}
|
||||
|
||||
static void modify_csi_measconfig(NR_CSI_MeasConfig_t *source, NR_CSI_MeasConfig_t *target)
|
||||
{
|
||||
if (source->reportTriggerSize)
|
||||
UPDATE_IE(target->reportTriggerSize, source->reportTriggerSize, long);
|
||||
if (source->semiPersistentOnPUSCH_TriggerStateList)
|
||||
HANDLE_SETUPRELEASE_IE(target->semiPersistentOnPUSCH_TriggerStateList,
|
||||
source->semiPersistentOnPUSCH_TriggerStateList,
|
||||
NR_CSI_SemiPersistentOnPUSCH_TriggerStateList_t,
|
||||
asn_DEF_NR_SetupRelease_CSI_SemiPersistentOnPUSCH_TriggerStateList);
|
||||
// NZP-CSI-RS-Resources
|
||||
if (source->nzp_CSI_RS_ResourceToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(source->nzp_CSI_RS_ResourceToReleaseList,
|
||||
target->nzp_CSI_RS_ResourceToAddModList,
|
||||
nzp_CSI_RS_ResourceId);
|
||||
}
|
||||
if (source->nzp_CSI_RS_ResourceToAddModList) {
|
||||
if (!target->nzp_CSI_RS_ResourceToAddModList)
|
||||
target->nzp_CSI_RS_ResourceToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceToAddModList));
|
||||
ADDMOD_IE_FROMLIST_WFUNCTION(source->nzp_CSI_RS_ResourceToAddModList,
|
||||
target->nzp_CSI_RS_ResourceToAddModList,
|
||||
nzp_CSI_RS_ResourceId,
|
||||
NR_NZP_CSI_RS_Resource_t,
|
||||
configure_csirs_resource);
|
||||
}
|
||||
// NZP-CSI-RS-ResourceSets
|
||||
if (source->nzp_CSI_RS_ResourceSetToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(source->nzp_CSI_RS_ResourceSetToReleaseList,
|
||||
target->nzp_CSI_RS_ResourceSetToAddModList,
|
||||
nzp_CSI_ResourceSetId);
|
||||
}
|
||||
if (source->nzp_CSI_RS_ResourceSetToAddModList) {
|
||||
if (!target->nzp_CSI_RS_ResourceSetToAddModList)
|
||||
target->nzp_CSI_RS_ResourceSetToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceSetToAddModList));
|
||||
ADDMOD_IE_FROMLIST(source->nzp_CSI_RS_ResourceSetToAddModList,
|
||||
target->nzp_CSI_RS_ResourceSetToAddModList,
|
||||
nzp_CSI_ResourceSetId,
|
||||
NR_NZP_CSI_RS_ResourceSet_t);
|
||||
}
|
||||
// CSI-IM-Resource
|
||||
if (source->csi_IM_ResourceToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(source->csi_IM_ResourceToReleaseList,
|
||||
target->csi_IM_ResourceToAddModList,
|
||||
csi_IM_ResourceId);
|
||||
}
|
||||
if (source->csi_IM_ResourceToAddModList) {
|
||||
if (!target->csi_IM_ResourceToAddModList)
|
||||
target->csi_IM_ResourceToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceToAddModList));
|
||||
ADDMOD_IE_FROMLIST_WFUNCTION(source->csi_IM_ResourceToAddModList,
|
||||
target->csi_IM_ResourceToAddModList,
|
||||
csi_IM_ResourceId,
|
||||
NR_CSI_IM_Resource_t,
|
||||
configure_csiim_resource);
|
||||
}
|
||||
// CSI-IM-ResourceSets
|
||||
if (source->csi_IM_ResourceSetToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(source->csi_IM_ResourceSetToReleaseList,
|
||||
target->csi_IM_ResourceSetToAddModList,
|
||||
csi_IM_ResourceSetId);
|
||||
}
|
||||
if (source->csi_IM_ResourceSetToAddModList) {
|
||||
if (!target->csi_IM_ResourceSetToAddModList)
|
||||
target->csi_IM_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceSetToAddModList));
|
||||
ADDMOD_IE_FROMLIST(source->csi_IM_ResourceSetToAddModList,
|
||||
target->csi_IM_ResourceSetToAddModList,
|
||||
csi_IM_ResourceSetId,
|
||||
NR_CSI_IM_ResourceSet_t);
|
||||
}
|
||||
// CSI-SSB-ResourceSets
|
||||
if (source->csi_SSB_ResourceSetToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(source->csi_SSB_ResourceSetToReleaseList,
|
||||
target->csi_SSB_ResourceSetToAddModList,
|
||||
csi_SSB_ResourceSetId);
|
||||
}
|
||||
if (source->csi_SSB_ResourceSetToAddModList) {
|
||||
if (!target->csi_SSB_ResourceSetToAddModList)
|
||||
target->csi_SSB_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_SSB_ResourceSetToAddModList));
|
||||
ADDMOD_IE_FROMLIST(source->csi_SSB_ResourceSetToAddModList,
|
||||
target->csi_SSB_ResourceSetToAddModList,
|
||||
csi_SSB_ResourceSetId,
|
||||
NR_CSI_SSB_ResourceSet_t);
|
||||
}
|
||||
// CSI-ResourceConfigs
|
||||
if (source->csi_ResourceConfigToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(source->csi_ResourceConfigToReleaseList,
|
||||
target->csi_ResourceConfigToAddModList,
|
||||
csi_ResourceConfigId);
|
||||
}
|
||||
if (source->csi_ResourceConfigToAddModList) {
|
||||
if (!target->csi_ResourceConfigToAddModList)
|
||||
target->csi_ResourceConfigToAddModList = calloc(1, sizeof(*target->csi_ResourceConfigToAddModList));
|
||||
ADDMOD_IE_FROMLIST(source->csi_ResourceConfigToAddModList,
|
||||
target->csi_ResourceConfigToAddModList,
|
||||
csi_ResourceConfigId,
|
||||
NR_CSI_ResourceConfig_t);
|
||||
}
|
||||
// CSI-ReportConfigs
|
||||
if (source->csi_ReportConfigToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(source->csi_ReportConfigToReleaseList,
|
||||
target->csi_ReportConfigToAddModList,
|
||||
reportConfigId);
|
||||
}
|
||||
if (source->csi_ReportConfigToAddModList) {
|
||||
if (!target->csi_ReportConfigToAddModList)
|
||||
target->csi_ReportConfigToAddModList = calloc(1, sizeof(*target->csi_ReportConfigToAddModList));
|
||||
ADDMOD_IE_FROMLIST(source->csi_ReportConfigToAddModList,
|
||||
target->csi_ReportConfigToAddModList,
|
||||
reportConfigId,
|
||||
NR_CSI_ReportConfig_t);
|
||||
}
|
||||
}
|
||||
|
||||
static void configure_csiconfig(NR_UE_ServingCell_Info_t *sc_info, struct NR_SetupRelease_CSI_MeasConfig *csi_MeasConfig_sr)
|
||||
{
|
||||
switch (csi_MeasConfig_sr->present) {
|
||||
case NR_SetupRelease_CSI_MeasConfig_PR_NOTHING:
|
||||
break;
|
||||
case NR_SetupRelease_CSI_MeasConfig_PR_release :
|
||||
case NR_SetupRelease_CSI_MeasConfig_PR_release:
|
||||
asn1cFreeStruc(asn_DEF_NR_CSI_MeasConfig, sc_info->csi_MeasConfig);
|
||||
asn1cFreeStruc(asn_DEF_NR_CSI_AperiodicTriggerStateList, sc_info->aperiodicTriggerStateList);
|
||||
break;
|
||||
case NR_SetupRelease_CSI_MeasConfig_PR_setup:
|
||||
case NR_SetupRelease_CSI_MeasConfig_PR_setup: {
|
||||
// separately handling aperiodicTriggerStateList
|
||||
// because it is set directly into sc_info structure
|
||||
if (csi_MeasConfig_sr->choice.setup->aperiodicTriggerStateList)
|
||||
HANDLE_SETUPRELEASE_DIRECT(sc_info->aperiodicTriggerStateList,
|
||||
csi_MeasConfig_sr->choice.setup->aperiodicTriggerStateList,
|
||||
NR_CSI_AperiodicTriggerStateList_t,
|
||||
asn_DEF_NR_CSI_AperiodicTriggerStateList);
|
||||
if (!sc_info->csi_MeasConfig) { // setup
|
||||
UPDATE_IE(sc_info->csi_MeasConfig, csi_MeasConfig_sr->choice.setup, NR_CSI_MeasConfig_t);
|
||||
} else { // modification
|
||||
NR_CSI_MeasConfig_t *target = sc_info->csi_MeasConfig;
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig = csi_MeasConfig_sr->choice.setup;
|
||||
if (csi_MeasConfig->reportTriggerSize)
|
||||
UPDATE_IE(target->reportTriggerSize, csi_MeasConfig->reportTriggerSize, long);
|
||||
if (csi_MeasConfig->aperiodicTriggerStateList)
|
||||
HANDLE_SETUPRELEASE_DIRECT(sc_info->aperiodicTriggerStateList,
|
||||
csi_MeasConfig->aperiodicTriggerStateList,
|
||||
NR_CSI_AperiodicTriggerStateList_t,
|
||||
asn_DEF_NR_CSI_AperiodicTriggerStateList);
|
||||
if (csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList)
|
||||
HANDLE_SETUPRELEASE_IE(target->semiPersistentOnPUSCH_TriggerStateList,
|
||||
csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList,
|
||||
NR_CSI_SemiPersistentOnPUSCH_TriggerStateList_t,
|
||||
asn_DEF_NR_SetupRelease_CSI_SemiPersistentOnPUSCH_TriggerStateList);
|
||||
// NZP-CSI-RS-Resources
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList,
|
||||
target->nzp_CSI_RS_ResourceToAddModList,
|
||||
nzp_CSI_RS_ResourceId);
|
||||
}
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList) {
|
||||
if (!target->nzp_CSI_RS_ResourceToAddModList)
|
||||
target->nzp_CSI_RS_ResourceToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceToAddModList));
|
||||
ADDMOD_IE_FROMLIST_WFUNCTION(csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList,
|
||||
target->nzp_CSI_RS_ResourceToAddModList,
|
||||
nzp_CSI_RS_ResourceId,
|
||||
NR_NZP_CSI_RS_Resource_t,
|
||||
configure_csirs_resource);
|
||||
}
|
||||
// NZP-CSI-RS-ResourceSets
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList,
|
||||
target->nzp_CSI_RS_ResourceSetToAddModList,
|
||||
nzp_CSI_ResourceSetId);
|
||||
}
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList) {
|
||||
if (!target->nzp_CSI_RS_ResourceSetToAddModList)
|
||||
target->nzp_CSI_RS_ResourceSetToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceSetToAddModList));
|
||||
ADDMOD_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList,
|
||||
target->nzp_CSI_RS_ResourceSetToAddModList,
|
||||
nzp_CSI_ResourceSetId,
|
||||
NR_NZP_CSI_RS_ResourceSet_t);
|
||||
}
|
||||
// CSI-IM-Resource
|
||||
if (csi_MeasConfig->csi_IM_ResourceToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceToReleaseList,
|
||||
target->csi_IM_ResourceToAddModList,
|
||||
csi_IM_ResourceId);
|
||||
}
|
||||
if (csi_MeasConfig->csi_IM_ResourceToAddModList) {
|
||||
if (!target->csi_IM_ResourceToAddModList)
|
||||
target->csi_IM_ResourceToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceToAddModList));
|
||||
ADDMOD_IE_FROMLIST_WFUNCTION(csi_MeasConfig->csi_IM_ResourceToAddModList,
|
||||
target->csi_IM_ResourceToAddModList,
|
||||
csi_IM_ResourceId,
|
||||
NR_CSI_IM_Resource_t,
|
||||
configure_csiim_resource);
|
||||
}
|
||||
// CSI-IM-ResourceSets
|
||||
if (csi_MeasConfig->csi_IM_ResourceSetToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceSetToReleaseList,
|
||||
target->csi_IM_ResourceSetToAddModList,
|
||||
csi_IM_ResourceSetId);
|
||||
}
|
||||
if (csi_MeasConfig->csi_IM_ResourceSetToAddModList) {
|
||||
if (!target->csi_IM_ResourceSetToAddModList)
|
||||
target->csi_IM_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceSetToAddModList));
|
||||
ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceSetToAddModList,
|
||||
target->csi_IM_ResourceSetToAddModList,
|
||||
csi_IM_ResourceSetId,
|
||||
NR_CSI_IM_ResourceSet_t);
|
||||
}
|
||||
// CSI-SSB-ResourceSets
|
||||
if (csi_MeasConfig->csi_SSB_ResourceSetToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(csi_MeasConfig->csi_SSB_ResourceSetToReleaseList,
|
||||
target->csi_SSB_ResourceSetToAddModList,
|
||||
csi_SSB_ResourceSetId);
|
||||
}
|
||||
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList) {
|
||||
if (!target->csi_SSB_ResourceSetToAddModList)
|
||||
target->csi_SSB_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_SSB_ResourceSetToAddModList));
|
||||
ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_SSB_ResourceSetToAddModList,
|
||||
target->csi_SSB_ResourceSetToAddModList,
|
||||
csi_SSB_ResourceSetId,
|
||||
NR_CSI_SSB_ResourceSet_t);
|
||||
}
|
||||
// CSI-ResourceConfigs
|
||||
if (csi_MeasConfig->csi_ResourceConfigToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(csi_MeasConfig->csi_ResourceConfigToReleaseList,
|
||||
target->csi_ResourceConfigToAddModList,
|
||||
csi_ResourceConfigId);
|
||||
}
|
||||
if (csi_MeasConfig->csi_ResourceConfigToAddModList) {
|
||||
if (!target->csi_ResourceConfigToAddModList)
|
||||
target->csi_ResourceConfigToAddModList = calloc(1, sizeof(*target->csi_ResourceConfigToAddModList));
|
||||
ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_ResourceConfigToAddModList,
|
||||
target->csi_ResourceConfigToAddModList,
|
||||
csi_ResourceConfigId,
|
||||
NR_CSI_ResourceConfig_t);
|
||||
}
|
||||
// CSI-ReportConfigs
|
||||
if (csi_MeasConfig->csi_ReportConfigToReleaseList) {
|
||||
RELEASE_IE_FROMLIST(csi_MeasConfig->csi_ReportConfigToReleaseList,
|
||||
target->csi_ReportConfigToAddModList,
|
||||
reportConfigId);
|
||||
}
|
||||
if (csi_MeasConfig->csi_ReportConfigToAddModList) {
|
||||
if (!target->csi_ReportConfigToAddModList)
|
||||
target->csi_ReportConfigToAddModList = calloc(1, sizeof(*target->csi_ReportConfigToAddModList));
|
||||
ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_ReportConfigToAddModList,
|
||||
target->csi_ReportConfigToAddModList,
|
||||
reportConfigId,
|
||||
NR_CSI_ReportConfig_t);
|
||||
}
|
||||
modify_csi_measconfig(csi_MeasConfig_sr->choice.setup, sc_info->csi_MeasConfig);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
AssertFatal(false, "Invalid case\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void configure_servingcell_info(NR_UE_ServingCell_Info_t *sc_info, NR_ServingCellConfig_t *scd)
|
||||
static void configure_servingcell_info(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd)
|
||||
{
|
||||
if (scd->csi_MeasConfig)
|
||||
NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info;
|
||||
if (scd->csi_MeasConfig) {
|
||||
configure_csiconfig(sc_info, scd->csi_MeasConfig);
|
||||
compute_csi_bitlen(sc_info->csi_MeasConfig, mac->csi_report_template);
|
||||
}
|
||||
|
||||
if (scd->supplementaryUplink)
|
||||
UPDATE_IE(sc_info->supplementaryUplink, scd->supplementaryUplink, NR_UplinkConfig_t);
|
||||
@@ -2226,7 +2238,7 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
||||
handle_reconfiguration_with_sync(mac, cc_idP, spCellConfig->reconfigurationWithSync);
|
||||
}
|
||||
if (scd) {
|
||||
configure_servingcell_info(&mac->sc_info, scd);
|
||||
configure_servingcell_info(mac, scd);
|
||||
configure_BWPs(mac, scd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,7 +394,6 @@ typedef struct {
|
||||
int n_harq;
|
||||
int n_CCE;
|
||||
int N_CCE;
|
||||
int delta_pucch;
|
||||
int initial_pucch_id;
|
||||
} PUCCH_sched_t;
|
||||
|
||||
@@ -482,6 +481,19 @@ typedef struct {
|
||||
A_SEQUENCE_OF(NR_SearchSpace_t) list_SS;
|
||||
} NR_BWP_PDCCH_t;
|
||||
|
||||
typedef struct csi_payload {
|
||||
uint32_t part1_payload;
|
||||
uint32_t part2_payload;
|
||||
int p1_bits;
|
||||
int p2_bits;
|
||||
} csi_payload_t;
|
||||
|
||||
typedef enum {
|
||||
WIDEBAND_ON_PUCCH,
|
||||
SUBBAND_ON_PUCCH,
|
||||
ON_PUSCH
|
||||
} CSI_mapping_t;
|
||||
|
||||
/*!\brief Top level UE MAC structure */
|
||||
typedef struct NR_UE_MAC_INST_s {
|
||||
module_id_t ue_id;
|
||||
@@ -578,7 +590,9 @@ typedef struct NR_UE_MAC_INST_s {
|
||||
|
||||
//SIDELINK MAC PARAMETERS
|
||||
sl_nr_ue_mac_params_t *SL_MAC_PARAMS;
|
||||
|
||||
// PUCCH closed loop power control state
|
||||
int G_b_f_c;
|
||||
bool pucch_power_control_initialized;
|
||||
} NR_UE_MAC_INST_t;
|
||||
|
||||
/*@}*/
|
||||
|
||||
@@ -111,6 +111,8 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac,
|
||||
void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info);
|
||||
void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info);
|
||||
|
||||
csi_payload_t nr_ue_aperiodic_csi_reporting(NR_UE_MAC_INST_t *mac, dci_field_t csi_request, int tda, long *K2);
|
||||
|
||||
/*! \fn int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id);
|
||||
\brief This function schedules a positive or negative SR for schedulingRequestID sr_id
|
||||
depending on the presence of any active SR and the prohibit timer.
|
||||
@@ -132,28 +134,26 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
|
||||
|
||||
int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch);
|
||||
|
||||
uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
|
||||
uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
CSI_mapping_t mapping_type);
|
||||
|
||||
csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
const NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
|
||||
uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
|
||||
uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
int csi_report_id,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||
int csi_report_id,
|
||||
CSI_mapping_t mapping_type,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
|
||||
uint8_t get_rsrp_index(int rsrp);
|
||||
uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp);
|
||||
@@ -217,23 +217,20 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||
uint8_t add_dmrs_flag,
|
||||
uint8_t N_symb_PUCCH,
|
||||
int subframe_number,
|
||||
int O_uci);
|
||||
|
||||
int get_deltatf(uint16_t nb_of_prbs,
|
||||
uint8_t N_symb_PUCCH,
|
||||
uint8_t freq_hop_flag,
|
||||
uint8_t add_dmrs_flag,
|
||||
int N_sc_ctrl_RB,
|
||||
int O_UCI);
|
||||
int O_uci,
|
||||
uint16_t start_prb);
|
||||
|
||||
int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
||||
int slot,
|
||||
frame_t frame,
|
||||
uint16_t rnti,
|
||||
PUCCH_sched_t *pucch,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
|
||||
int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int N_RB_UL, bool is_transform_precoding, int n_prbs, int start_prb);
|
||||
|
||||
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame);
|
||||
|
||||
/* Random Access */
|
||||
|
||||
/* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x
|
||||
@@ -243,7 +240,7 @@ and fills the PRACH PDU per each FD occasion.
|
||||
@param slotP Slot index
|
||||
@returns void
|
||||
*/
|
||||
void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, void *phy_data);
|
||||
void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP);
|
||||
void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot);
|
||||
void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot);
|
||||
|
||||
@@ -367,6 +364,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
NR_tda_info_t *tda_info,
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
|
||||
dci_pdu_rel15_t *dci,
|
||||
csi_payload_t *csi_report,
|
||||
RAR_grant_t *rar_grant,
|
||||
uint16_t rnti,
|
||||
int ss_type,
|
||||
|
||||
@@ -82,6 +82,8 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
||||
|
||||
for (int i = 0; i < NR_MAX_SR_ID; i++)
|
||||
memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i]));
|
||||
|
||||
mac->pucch_power_control_initialized = false;
|
||||
}
|
||||
|
||||
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
|
||||
|
||||
@@ -930,7 +930,6 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
|
||||
mac->nr_ue_emul_l1.num_harqs = 1;
|
||||
PUCCH_sched_t pucch = {.n_CCE = current_harq->n_CCE,
|
||||
.N_CCE = current_harq->N_CCE,
|
||||
.delta_pucch = current_harq->delta_pucch,
|
||||
.ack_payload = ack_nack,
|
||||
.n_harq = 1};
|
||||
current_harq->active = false;
|
||||
@@ -943,7 +942,7 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
|
||||
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
|
||||
if (!pdu)
|
||||
return;
|
||||
int ret = nr_ue_configure_pucch(mac, sched_slot, mac->ra.t_crnti, &pucch, &pdu->pucch_config_pdu);
|
||||
int ret = nr_ue_configure_pucch(mac, sched_slot, sched_frame, mac->ra.t_crnti, &pucch, &pdu->pucch_config_pdu);
|
||||
if (ret != 0)
|
||||
remove_ul_config_last_item(pdu);
|
||||
release_ul_config(pdu, false);
|
||||
|
||||
@@ -31,6 +31,40 @@
|
||||
|
||||
#include "LAYER2/NR_MAC_UE/mac_proto.h"
|
||||
|
||||
#define DEFAULT_P0_NOMINAL_PUCCH_0_DBM 0
|
||||
#define DEFAULT_DELTA_F_PUCCH_0_DB 0
|
||||
|
||||
// TODO: This should be part of mac instance
|
||||
/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */
|
||||
/* this is a counter of number of pucch format 4 per subframe */
|
||||
static int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] = {0};
|
||||
|
||||
/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */
|
||||
static const int nb_symbols_excluding_dmrs[11][2][2]
|
||||
= {
|
||||
/* No additional DMRS Additional DMRS */
|
||||
/* PUCCH length No hopping hopping No hopping hopping */
|
||||
/* index 0 1 0 1 */
|
||||
/* 4 */ {{ 3 , 2 } , { 3 , 2 }},
|
||||
/* 5 */ {{ 3 , 3 } , { 3 , 3 }},
|
||||
/* 6 */ {{ 4 , 4 } , { 4 , 4 }},
|
||||
/* 7 */ {{ 5 , 5 } , { 5 , 5 }},
|
||||
/* 8 */ {{ 6 , 6 } , { 6 , 6 }},
|
||||
/* 9 */ {{ 7 , 7 } , { 7 , 7 }},
|
||||
/* 10 */ {{ 8 , 8 } , { 6 , 6 }},
|
||||
/* 11 */ {{ 9 , 9 } , { 7 , 7 }},
|
||||
/* 12 */ {{ 10 , 10 } , { 8 , 8 }},
|
||||
/* 13 */ {{ 11 , 11 } , { 9 , 9 }},
|
||||
/* 14 */ {{ 12 , 12 } , { 10 , 10 }},
|
||||
};
|
||||
|
||||
static int get_deltatf(uint16_t nb_of_prbs,
|
||||
uint8_t N_symb_PUCCH,
|
||||
uint8_t freq_hop_flag,
|
||||
uint8_t add_dmrs_flag,
|
||||
int N_sc_ctrl_RB,
|
||||
int O_UCI);
|
||||
|
||||
// Implementation of 6.2.4 Configured ransmitted power
|
||||
// 3GPP TS 38.101-1 version 16.5.0 Release 16
|
||||
// -
|
||||
@@ -156,3 +190,171 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs,
|
||||
}
|
||||
}
|
||||
|
||||
// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback
|
||||
// slot. The correct way to do this would be to calculate the K_PUCCH (delta_PUCCH summation window end) for each PUCCH occasion and
|
||||
// compare PUCCH transmission symbol with the reception symbol of the DCI containing delta_PUCCH to determine if the delta_PUCCH
|
||||
// should be added at each occasion.
|
||||
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame)
|
||||
{
|
||||
int delta_tpc_sum = 0;
|
||||
for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
|
||||
if (mac->dl_harq_info[i].active && mac->dl_harq_info[i].ul_slot == slot && mac->dl_harq_info[i].ul_frame == frame) {
|
||||
delta_tpc_sum += mac->dl_harq_info[i].delta_pucch;
|
||||
mac->dl_harq_info[i].delta_pucch = 0;
|
||||
}
|
||||
}
|
||||
return delta_tpc_sum;
|
||||
}
|
||||
|
||||
// PUCCH Power control according to 38.213 section 7.2.1
|
||||
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||
int scs,
|
||||
NR_PUCCH_Config_t *pucch_Config,
|
||||
int sum_delta_pucch,
|
||||
uint8_t format_type,
|
||||
uint16_t nb_of_prbs,
|
||||
uint8_t freq_hop_flag,
|
||||
uint8_t add_dmrs_flag,
|
||||
uint8_t N_symb_PUCCH,
|
||||
int subframe_number,
|
||||
int O_uci,
|
||||
uint16_t start_prb)
|
||||
{
|
||||
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
|
||||
AssertFatal(current_UL_BWP && current_UL_BWP->pucch_ConfigCommon,
|
||||
"Missing configuration: need UL_BWP and pucch_ConfigCommon to calculate PUCCH tx power\n");
|
||||
int PUCCH_POWER_DEFAULT = 0;
|
||||
// p0_nominal is optional
|
||||
int16_t P_O_NOMINAL_PUCCH = DEFAULT_P0_NOMINAL_PUCCH_0_DBM;
|
||||
if (current_UL_BWP->pucch_ConfigCommon->p0_nominal != NULL) {
|
||||
P_O_NOMINAL_PUCCH = *current_UL_BWP->pucch_ConfigCommon->p0_nominal;
|
||||
}
|
||||
|
||||
struct NR_PUCCH_PowerControl *power_config = pucch_Config ? pucch_Config->pucch_PowerControl : NULL;
|
||||
|
||||
if (!power_config)
|
||||
return (PUCCH_POWER_DEFAULT);
|
||||
|
||||
int16_t P_O_UE_PUCCH = 0;
|
||||
|
||||
if (pucch_Config->spatialRelationInfoToAddModList != NULL) { /* FFS TODO NR */
|
||||
LOG_D(MAC,"PUCCH Spatial relation infos are not yet implemented\n");
|
||||
return (PUCCH_POWER_DEFAULT);
|
||||
}
|
||||
|
||||
int G_b_f_c = 0;
|
||||
if (power_config->p0_Set != NULL) {
|
||||
P_O_UE_PUCCH = power_config->p0_Set->list.array[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */
|
||||
}
|
||||
|
||||
int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH;
|
||||
|
||||
int16_t delta_F_PUCCH = DEFAULT_DELTA_F_PUCCH_0_DB;
|
||||
long *delta_F_PUCCH_config = NULL;
|
||||
int DELTA_TF;
|
||||
uint16_t N_ref_PUCCH;
|
||||
int N_sc_ctrl_RB = 0;
|
||||
|
||||
/* computing of pucch transmission power adjustment */
|
||||
switch (format_type) {
|
||||
case 0:
|
||||
N_ref_PUCCH = 2;
|
||||
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f0;
|
||||
break;
|
||||
case 1:
|
||||
N_ref_PUCCH = 14;
|
||||
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH * O_uci);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f1;
|
||||
break;
|
||||
case 2:
|
||||
N_sc_ctrl_RB = 10;
|
||||
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f2;
|
||||
break;
|
||||
case 3:
|
||||
N_sc_ctrl_RB = 14;
|
||||
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f3;
|
||||
break;
|
||||
case 4:
|
||||
N_sc_ctrl_RB = 14/(nb_pucch_format_4_in_subframes[subframe_number]);
|
||||
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f4;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
LOG_E(MAC,"PUCCH unknown pucch format %d\n", format_type);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (delta_F_PUCCH_config != NULL) {
|
||||
delta_F_PUCCH = *delta_F_PUCCH_config;
|
||||
}
|
||||
|
||||
// PUCCH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1)
|
||||
// TODO: P_CMAX for format 2
|
||||
int P_CMAX = nr_get_Pcmax(mac, 2, false, mac->current_UL_BWP->scs, mac->current_UL_BWP->BWPSize, true, 1, start_prb);
|
||||
int P_CMIN = -40; // TODO: minimum TX power, possibly 38.101-1 6.3.1
|
||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||
|
||||
if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) {
|
||||
LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented\n");
|
||||
return (PUCCH_POWER_DEFAULT);
|
||||
}
|
||||
int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs)));
|
||||
|
||||
int16_t pucch_power_without_g_pucch = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF;
|
||||
|
||||
if (power_config->p0_Set == NULL) {
|
||||
if (mac->pucch_power_control_initialized == false) {
|
||||
// Initialize power control state
|
||||
// Assuming only sending on PCell
|
||||
NR_PRACH_RESOURCES_t* prach_resources = &mac->ra.prach_resources;
|
||||
float DELTA_P_rampup_requested = (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
|
||||
float DELTA_P_rampup = P_CMAX - (P_O_PUCCH + pathloss + delta_F_PUCCH + DELTA_TF + sum_delta_pucch);
|
||||
DELTA_P_rampup = max(min(0, DELTA_P_rampup), DELTA_P_rampup_requested);
|
||||
mac->G_b_f_c = DELTA_P_rampup + sum_delta_pucch;
|
||||
mac->pucch_power_control_initialized = true;
|
||||
}
|
||||
else {
|
||||
// PUCCH closed loop power control state
|
||||
G_b_f_c = mac->G_b_f_c;
|
||||
if (!((pucch_power_without_g_pucch + G_b_f_c >= P_CMAX && sum_delta_pucch > 0) ||
|
||||
(pucch_power_without_g_pucch + G_b_f_c <= P_CMIN && sum_delta_pucch < 0))) {
|
||||
G_b_f_c += sum_delta_pucch;
|
||||
}
|
||||
mac->G_b_f_c = G_b_f_c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int pucch_power = min(P_CMAX, pucch_power_without_g_pucch + G_b_f_c);
|
||||
|
||||
LOG_D(MAC, "PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n",
|
||||
pucch_power, M_pucch_component, pathloss, delta_F_PUCCH, DELTA_TF, G_b_f_c);
|
||||
|
||||
return pucch_power;
|
||||
}
|
||||
|
||||
static int get_deltatf(uint16_t nb_of_prbs,
|
||||
uint8_t N_symb_PUCCH,
|
||||
uint8_t freq_hop_flag,
|
||||
uint8_t add_dmrs_flag,
|
||||
int N_sc_ctrl_RB,
|
||||
int O_UCI)
|
||||
{
|
||||
int DELTA_TF;
|
||||
int O_CRC = compute_pucch_crc_size(O_UCI);
|
||||
int N_symb = N_symb_PUCCH < 4 ? N_symb_PUCCH : nb_symbols_excluding_dmrs[N_symb_PUCCH - 4][add_dmrs_flag][freq_hop_flag];
|
||||
float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb;
|
||||
float K1 = 6;
|
||||
if (O_UCI + O_CRC < 12)
|
||||
DELTA_TF = 10 * log10((double)(((K1 * (O_UCI)) / N_RE)));
|
||||
else {
|
||||
float K2 = 2.4;
|
||||
float BPRE = (O_UCI + O_CRC) / N_RE;
|
||||
DELTA_TF = 10 * log10((double)(pow(2, (K2 * BPRE)) - 1));
|
||||
}
|
||||
return DELTA_TF;
|
||||
}
|
||||
|
||||
@@ -58,18 +58,11 @@
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
#define DEFAULT_P0_NOMINAL_PUCCH_0_DBM 0
|
||||
#define DEFAULT_DELTA_F_PUCCH_0_DB 0
|
||||
|
||||
// #define DEBUG_MIB
|
||||
// #define ENABLE_MAC_PAYLOAD_DEBUG 1
|
||||
// #define DEBUG_RAR
|
||||
extern uint32_t N_RB_DL;
|
||||
|
||||
/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */
|
||||
/* this is a counter of number of pucch format 4 per subframe */
|
||||
static int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] = { 0 } ;
|
||||
|
||||
/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */
|
||||
static const int sequence_cyclic_shift_1_harq_ack_bit[2]
|
||||
/* HARQ-ACK Value 0 1 */
|
||||
@@ -126,25 +119,6 @@ int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const
|
||||
return mcs;
|
||||
}
|
||||
|
||||
/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */
|
||||
static const int nb_symbols_excluding_dmrs[11][2][2]
|
||||
= {
|
||||
/* No additional DMRS Additional DMRS */
|
||||
/* PUCCH length No hopping hopping No hopping hopping */
|
||||
/* index 0 1 0 1 */
|
||||
/* 4 */ {{ 3 , 2 } , { 3 , 2 }},
|
||||
/* 5 */ {{ 3 , 3 } , { 3 , 3 }},
|
||||
/* 6 */ {{ 4 , 4 } , { 4 , 4 }},
|
||||
/* 7 */ {{ 5 , 5 } , { 5 , 5 }},
|
||||
/* 8 */ {{ 6 , 6 } , { 6 , 6 }},
|
||||
/* 9 */ {{ 7 , 7 } , { 7 , 7 }},
|
||||
/* 10 */ {{ 8 , 8 } , { 6 , 6 }},
|
||||
/* 11 */ {{ 9 , 9 } , { 7 , 7 }},
|
||||
/* 12 */ {{ 10 , 10 } , { 8 , 8 }},
|
||||
/* 13 */ {{ 11 , 11 } , { 9 , 9 }},
|
||||
/* 14 */ {{ 12 , 12 } , { 10 , 10 }},
|
||||
};
|
||||
|
||||
/* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
|
||||
const initial_pucch_resource_t initial_pucch_resource[16] = {
|
||||
/* format first symbol Number of symbols PRB offset nb index for set of initial CS */
|
||||
@@ -443,7 +417,15 @@ static int nr_ue_process_dci_ul_00(NR_UE_MAC_INST_t *mac,
|
||||
if (!pdu)
|
||||
return -1;
|
||||
|
||||
int ret = nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, dci, NULL, dci_ind->rnti, dci_ind->ss_type, NR_UL_DCI_FORMAT_0_0);
|
||||
int ret = nr_config_pusch_pdu(mac,
|
||||
&tda_info,
|
||||
&pdu->pusch_config_pdu,
|
||||
dci,
|
||||
NULL,
|
||||
NULL,
|
||||
dci_ind->rnti,
|
||||
dci_ind->ss_type,
|
||||
NR_UL_DCI_FORMAT_0_0);
|
||||
if (ret != 0)
|
||||
remove_ul_config_last_item(pdu);
|
||||
release_ul_config(pdu, false);
|
||||
@@ -489,6 +471,12 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac,
|
||||
// - SECOND_DAI
|
||||
// - SRS_RESOURCE_IND
|
||||
|
||||
/* CSI_REQUEST */
|
||||
long csi_K2 = -1;
|
||||
csi_payload_t csi_report = {0};
|
||||
if (dci->csi_request.nbits > 0 && dci->csi_request.val > 0)
|
||||
csi_report = nr_ue_aperiodic_csi_reporting(mac, dci->csi_request, dci->time_domain_assignment.val, &csi_K2);
|
||||
|
||||
/* SRS_REQUEST */
|
||||
AssertFatal(dci->srs_request.nbits == 2, "If SUL is supported in the cell, there is an additional bit in SRS request field\n");
|
||||
if (dci->srs_request.val > 0)
|
||||
@@ -504,6 +492,13 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac,
|
||||
dci_ind->ss_type,
|
||||
get_rnti_type(mac, dci_ind->rnti),
|
||||
dci->time_domain_assignment.val);
|
||||
|
||||
if (dci->ulsch_indicator == 0) {
|
||||
// in case of CSI on PUSCH and no ULSCH we need to use reportSlotOffset in trigger state
|
||||
AssertFatal(csi_K2 > 0, "Invalid CSI K2 value %ld\n", csi_K2);
|
||||
tda_info.k2 = csi_K2;
|
||||
}
|
||||
|
||||
if (tda_info.nrOfSymbols == 0)
|
||||
return -1;
|
||||
|
||||
@@ -515,7 +510,15 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac,
|
||||
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
|
||||
if (!pdu)
|
||||
return -1;
|
||||
int ret = nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, dci, NULL, dci_ind->rnti, dci_ind->ss_type, NR_UL_DCI_FORMAT_0_1);
|
||||
int ret = nr_config_pusch_pdu(mac,
|
||||
&tda_info,
|
||||
&pdu->pusch_config_pdu,
|
||||
dci,
|
||||
&csi_report,
|
||||
NULL,
|
||||
dci_ind->rnti,
|
||||
dci_ind->ss_type,
|
||||
NR_UL_DCI_FORMAT_0_1);
|
||||
if (ret != 0)
|
||||
remove_ul_config_last_item(pdu);
|
||||
release_ul_config(pdu, false);
|
||||
@@ -1381,6 +1384,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
|
||||
|
||||
int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
||||
int slot,
|
||||
frame_t frame,
|
||||
uint16_t rnti,
|
||||
PUCCH_sched_t *pucch,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu)
|
||||
@@ -1393,8 +1397,6 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
||||
const int scs = current_UL_BWP->scs;
|
||||
|
||||
int subframe_number = slot / (nr_slots_per_frame[scs]/10);
|
||||
nb_pucch_format_4_in_subframes[subframe_number] = 0;
|
||||
|
||||
pucch_pdu->rnti = rnti;
|
||||
|
||||
LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource);
|
||||
@@ -1579,17 +1581,20 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sum_delta_pucch = get_sum_delta_pucch(mac, slot, frame);
|
||||
|
||||
pucch_pdu->pucch_tx_power = get_pucch_tx_power_ue(mac,
|
||||
scs,
|
||||
pucch_Config,
|
||||
pucch->delta_pucch,
|
||||
sum_delta_pucch,
|
||||
pucch_pdu->format_type,
|
||||
pucch_pdu->prb_size,
|
||||
pucch_pdu->freq_hop_flag,
|
||||
pucch_pdu->add_dmrs_flag,
|
||||
pucch_pdu->nr_of_symbols,
|
||||
subframe_number,
|
||||
n_uci);
|
||||
n_uci,
|
||||
pucch_pdu->prb_start);
|
||||
} else {
|
||||
LOG_E(NR_MAC, "problem with pucch configuration\n");
|
||||
return -1;
|
||||
@@ -1625,135 +1630,6 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// PUCCH Power control according to 38.213 section 7.2.1
|
||||
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||
int scs,
|
||||
NR_PUCCH_Config_t *pucch_Config,
|
||||
int delta_pucch,
|
||||
uint8_t format_type,
|
||||
uint16_t nb_of_prbs,
|
||||
uint8_t freq_hop_flag,
|
||||
uint8_t add_dmrs_flag,
|
||||
uint8_t N_symb_PUCCH,
|
||||
int subframe_number,
|
||||
int O_uci)
|
||||
{
|
||||
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
|
||||
AssertFatal(current_UL_BWP && current_UL_BWP->pucch_ConfigCommon,
|
||||
"Missing configuration: need UL_BWP and pucch_ConfigCommon to calculate PUCCH tx power\n");
|
||||
int PUCCH_POWER_DEFAULT = 0;
|
||||
// p0_nominal is optional
|
||||
int16_t P_O_NOMINAL_PUCCH = DEFAULT_P0_NOMINAL_PUCCH_0_DBM;
|
||||
if (current_UL_BWP->pucch_ConfigCommon->p0_nominal != NULL) {
|
||||
P_O_NOMINAL_PUCCH = *current_UL_BWP->pucch_ConfigCommon->p0_nominal;
|
||||
}
|
||||
|
||||
struct NR_PUCCH_PowerControl *power_config = pucch_Config ? pucch_Config->pucch_PowerControl : NULL;
|
||||
|
||||
if (!power_config)
|
||||
return (PUCCH_POWER_DEFAULT);
|
||||
|
||||
int16_t P_O_UE_PUCCH;
|
||||
int16_t G_b_f_c = 0;
|
||||
|
||||
if (pucch_Config->spatialRelationInfoToAddModList != NULL) { /* FFS TODO NR */
|
||||
LOG_D(MAC,"PUCCH Spatial relation infos are not yet implemented\n");
|
||||
return (PUCCH_POWER_DEFAULT);
|
||||
}
|
||||
|
||||
if (power_config->p0_Set != NULL) {
|
||||
P_O_UE_PUCCH = power_config->p0_Set->list.array[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */
|
||||
G_b_f_c = 0;
|
||||
}
|
||||
else {
|
||||
G_b_f_c = delta_pucch;
|
||||
LOG_E(MAC,"PUCCH Transmit power control command not yet implemented for NR\n");
|
||||
return (PUCCH_POWER_DEFAULT);
|
||||
}
|
||||
|
||||
int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH;
|
||||
|
||||
int16_t delta_F_PUCCH = DEFAULT_DELTA_F_PUCCH_0_DB;
|
||||
long *delta_F_PUCCH_config = NULL;
|
||||
int DELTA_TF;
|
||||
uint16_t N_ref_PUCCH;
|
||||
int N_sc_ctrl_RB = 0;
|
||||
|
||||
/* computing of pucch transmission power adjustment */
|
||||
switch (format_type) {
|
||||
case 0:
|
||||
N_ref_PUCCH = 2;
|
||||
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f0;
|
||||
break;
|
||||
case 1:
|
||||
N_ref_PUCCH = 14;
|
||||
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f1;
|
||||
break;
|
||||
case 2:
|
||||
N_sc_ctrl_RB = 10;
|
||||
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f2;
|
||||
break;
|
||||
case 3:
|
||||
N_sc_ctrl_RB = 14;
|
||||
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f3;
|
||||
break;
|
||||
case 4:
|
||||
N_sc_ctrl_RB = 14/(nb_pucch_format_4_in_subframes[subframe_number]);
|
||||
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f4;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
LOG_E(MAC,"PUCCH unknown pucch format %d\n", format_type);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (delta_F_PUCCH_config != NULL) {
|
||||
delta_F_PUCCH = *delta_F_PUCCH_config;
|
||||
}
|
||||
|
||||
if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) {
|
||||
LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented\n");
|
||||
return (PUCCH_POWER_DEFAULT);
|
||||
}
|
||||
|
||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||
int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs)));
|
||||
|
||||
int16_t pucch_power = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF + G_b_f_c;
|
||||
|
||||
LOG_D(MAC, "PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n",
|
||||
pucch_power, M_pucch_component, pathloss, delta_F_PUCCH, DELTA_TF, G_b_f_c);
|
||||
|
||||
return (pucch_power);
|
||||
}
|
||||
|
||||
int get_deltatf(uint16_t nb_of_prbs,
|
||||
uint8_t N_symb_PUCCH,
|
||||
uint8_t freq_hop_flag,
|
||||
uint8_t add_dmrs_flag,
|
||||
int N_sc_ctrl_RB,
|
||||
int O_UCI)
|
||||
{
|
||||
int DELTA_TF;
|
||||
int O_CRC = compute_pucch_crc_size(O_UCI);
|
||||
int N_symb = N_symb_PUCCH < 4 ? N_symb_PUCCH : nb_symbols_excluding_dmrs[N_symb_PUCCH - 4][add_dmrs_flag][freq_hop_flag];
|
||||
float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb;
|
||||
float K1 = 6;
|
||||
if (O_UCI + O_CRC < 12)
|
||||
DELTA_TF = 10 * log10((double)(((K1 * (O_UCI)) / N_RE)));
|
||||
else {
|
||||
float K2 = 2.4;
|
||||
float BPRE = (O_UCI + O_CRC) / N_RE;
|
||||
DELTA_TF = 10 * log10((double)(pow(2,(K2*BPRE)) - 1));
|
||||
}
|
||||
return DELTA_TF;
|
||||
}
|
||||
|
||||
static int find_pucch_resource_set(NR_PUCCH_Config_t *pucch_Config, int size)
|
||||
{
|
||||
// Procedure described in 38.213 Section 9.2.1
|
||||
@@ -2362,7 +2238,6 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
|
||||
res_ind = temp_ind;
|
||||
pucch->n_CCE = current_harq->n_CCE;
|
||||
pucch->N_CCE = current_harq->N_CCE;
|
||||
pucch->delta_pucch = current_harq->delta_pucch;
|
||||
LOG_D(NR_MAC,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid);
|
||||
}
|
||||
}
|
||||
@@ -2584,14 +2459,12 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC
|
||||
NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig;
|
||||
|
||||
int csi_priority = INT_MAX;
|
||||
for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||
for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++) {
|
||||
NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||
|
||||
if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic){
|
||||
|
||||
if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic) {
|
||||
int period, offset;
|
||||
csi_period_offset(csirep, NULL, &period, &offset);
|
||||
|
||||
const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
|
||||
if (((n_slots_frame*frame + slot - offset)%period) == 0 && pucch_Config) {
|
||||
int csi_res_id = -1;
|
||||
@@ -2619,47 +2492,50 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC
|
||||
// we discard previous report
|
||||
csi_priority = temp_priority;
|
||||
num_csi = 1;
|
||||
pucch->n_csi = nr_get_csi_payload(mac, pucch, csi_report_id, csi_measconfig);
|
||||
csi_payload_t csi = nr_get_csi_payload(mac, csi_report_id, WIDEBAND_ON_PUCCH, csi_measconfig);
|
||||
pucch->n_csi = csi.p1_bits;
|
||||
pucch->csi_part1_payload = csi.part1_payload;
|
||||
pucch->pucch_resource = csi_pucch;
|
||||
} else
|
||||
continue;
|
||||
} else {
|
||||
num_csi = 1;
|
||||
csi_priority = temp_priority;
|
||||
pucch->n_csi = nr_get_csi_payload(mac, pucch, csi_report_id, csi_measconfig);
|
||||
csi_payload_t csi = nr_get_csi_payload(mac, csi_report_id, WIDEBAND_ON_PUCCH, csi_measconfig);
|
||||
pucch->n_csi = csi.p1_bits;
|
||||
pucch->csi_part1_payload = csi.part1_payload;
|
||||
pucch->pucch_resource = csi_pucch;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Only periodic CSI reporting is currently implemented\n");
|
||||
AssertFatal(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_aperiodic,
|
||||
"Not supported CSI report type\n");
|
||||
}
|
||||
}
|
||||
return num_csi;
|
||||
}
|
||||
|
||||
uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
int csi_report_id,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||
|
||||
int n_csi_bits = 0;
|
||||
|
||||
AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count>0,"No CSI Report configuration available\n");
|
||||
|
||||
csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||
int csi_report_id,
|
||||
CSI_mapping_t mapping_type,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig)
|
||||
{
|
||||
AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count > 0,"No CSI Report configuration available\n");
|
||||
csi_payload_t csi = {0};
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
||||
switch(csi_reportconfig->reportQuantity.present) {
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_none:
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||
n_csi_bits = get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||
csi = get_ssb_rsrp_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||
n_csi_bits = get_csirs_RI_PMI_CQI_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||
csi = get_csirs_RI_PMI_CQI_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig, mapping_type);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||
n_csi_bits = get_csirs_RSRP_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||
csi = get_csirs_RSRP_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
|
||||
@@ -2670,16 +2546,15 @@ uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
|
||||
}
|
||||
return (n_csi_bits);
|
||||
return csi;
|
||||
}
|
||||
|
||||
|
||||
uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||
|
||||
csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig)
|
||||
{
|
||||
int nb_ssb = 0; // nb of ssb in the resource
|
||||
int nb_meas = 0; // nb of ssb to report measurements on
|
||||
int bits = 0;
|
||||
@@ -2750,18 +2625,22 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||
break; // resorce found
|
||||
}
|
||||
}
|
||||
pucch->csi_part1_payload = temp_payload;
|
||||
return bits;
|
||||
AssertFatal(bits <= 32, "Not supporting CSI report with more than 32 bits\n");
|
||||
csi_payload_t csi = {.part1_payload = temp_payload, .p1_bits = bits, csi.p2_bits = 0};
|
||||
return csi;
|
||||
}
|
||||
|
||||
uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||
|
||||
int n_bits = 0;
|
||||
uint64_t temp_payload = 0;
|
||||
csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
CSI_mapping_t mapping_type)
|
||||
{
|
||||
int p1_bits = 0;
|
||||
int p2_bits = 0;
|
||||
uint64_t temp_payload_1 = 0;
|
||||
uint64_t temp_payload_2 = 0;
|
||||
AssertFatal(mapping_type != SUBBAND_ON_PUCCH, "CSI mapping for subband PMI and CQI not implemented\n");
|
||||
|
||||
for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
|
||||
|
||||
@@ -2772,16 +2651,19 @@ uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
||||
|
||||
nr_csi_report_t *csi_report = &mac->csi_report_template[csi_idx];
|
||||
compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template);
|
||||
n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_idx);
|
||||
|
||||
nr_csi_report_t *csi_report = NULL;
|
||||
for (int i = 0; i < MAX_CSI_REPORTCONFIG; i++) {
|
||||
if (mac->csi_report_template[i].reportConfigId == csi_reportconfig->reportConfigId) {
|
||||
csi_report = &mac->csi_report_template[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(csi_report, "Couldn't find CSI report with ID %ld\n", csi_reportconfig->reportConfigId);
|
||||
int cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||
int ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||
int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->csirs_measurements.rank_indicator];
|
||||
int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->csirs_measurements.rank_indicator];
|
||||
int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->csirs_measurements.rank_indicator];
|
||||
int padding_bitlen = n_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen);
|
||||
|
||||
if (get_softmodem_params()->emulate_l1) {
|
||||
static const uint8_t mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
|
||||
@@ -2794,38 +2676,53 @@ uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||
mac->csirs_measurements.cqi = mcs_to_cqi[mcs];
|
||||
}
|
||||
|
||||
int padding_bitlen = 0;
|
||||
// TODO: Improvements will be needed to cri_bitlen>0 and pmi_x1_bitlen>0
|
||||
temp_payload = (mac->csirs_measurements.rank_indicator<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen+padding_bitlen+pmi_x1_bitlen)) |
|
||||
(mac->csirs_measurements.i1<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen)) |
|
||||
(mac->csirs_measurements.i2<<(cri_bitlen+cqi_bitlen)) |
|
||||
(mac->csirs_measurements.cqi<<cri_bitlen) |
|
||||
0;
|
||||
|
||||
temp_payload = reverse_bits(temp_payload, n_bits);
|
||||
if (mapping_type == ON_PUSCH) {
|
||||
p1_bits = cri_bitlen + ri_bitlen + cqi_bitlen;
|
||||
p2_bits = pmi_x1_bitlen + pmi_x2_bitlen;
|
||||
temp_payload_1 = (0/*mac->csi_measurements.cri*/ << (cqi_bitlen + ri_bitlen)) |
|
||||
(mac->csirs_measurements.rank_indicator << cqi_bitlen) |
|
||||
(mac->csirs_measurements.cqi);
|
||||
temp_payload_2 = (mac->csirs_measurements.i1 << pmi_x2_bitlen) |
|
||||
mac->csirs_measurements.i2;
|
||||
}
|
||||
else {
|
||||
p1_bits = nr_get_csi_bitlen(csi_report);
|
||||
padding_bitlen = p1_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen);
|
||||
temp_payload_1 = (0/*mac->csi_measurements.cri*/ << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen + ri_bitlen)) |
|
||||
(mac->csirs_measurements.rank_indicator << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen)) |
|
||||
(mac->csirs_measurements.i1 << (cqi_bitlen + pmi_x2_bitlen)) |
|
||||
(mac->csirs_measurements.i2 << (cqi_bitlen)) |
|
||||
(mac->csirs_measurements.cqi);
|
||||
}
|
||||
|
||||
temp_payload_1 = reverse_bits(temp_payload_1, p1_bits);
|
||||
temp_payload_2 = reverse_bits(temp_payload_2, p2_bits);
|
||||
LOG_D(NR_MAC, "cri_bitlen = %d\n", cri_bitlen);
|
||||
LOG_D(NR_MAC, "ri_bitlen = %d\n", ri_bitlen);
|
||||
LOG_D(NR_MAC, "pmi_x1_bitlen = %d\n", pmi_x1_bitlen);
|
||||
LOG_D(NR_MAC, "pmi_x2_bitlen = %d\n", pmi_x2_bitlen);
|
||||
LOG_D(NR_MAC, "cqi_bitlen = %d\n", cqi_bitlen);
|
||||
LOG_D(NR_MAC, "csi_part1_payload = 0x%lx\n", temp_payload);
|
||||
LOG_D(NR_MAC, "n_bits = %d\n", n_bits);
|
||||
|
||||
LOG_D(NR_MAC, "csi_part1_payload = 0x%lx\n", temp_payload_1);
|
||||
LOG_D(NR_MAC, "csi_part2_payload = 0x%lx\n", temp_payload_2);
|
||||
LOG_D(NR_MAC, "part1_bits = %d\n", p1_bits);
|
||||
LOG_D(NR_MAC, "part2_bits = %d\n", p2_bits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pucch->csi_part1_payload = temp_payload;
|
||||
return n_bits;
|
||||
AssertFatal(p1_bits <= 32 && p2_bits <= 32, "Not supporting CSI report with more than 32 bits\n");
|
||||
csi_payload_t csi = {.part1_payload = temp_payload_1, .part2_payload = temp_payload_2, .p1_bits = p1_bits, csi.p2_bits = p2_bits};
|
||||
return csi;
|
||||
}
|
||||
|
||||
uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||
|
||||
csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
const NR_CSI_MeasConfig_t *csi_MeasConfig)
|
||||
{
|
||||
int n_bits = 0;
|
||||
uint64_t temp_payload = 0;
|
||||
|
||||
@@ -2838,10 +2735,15 @@ uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
||||
|
||||
nr_csi_report_t *csi_report = &mac->csi_report_template[csi_idx];
|
||||
compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template);
|
||||
n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_idx);
|
||||
|
||||
nr_csi_report_t *csi_report = NULL;
|
||||
for (int i = 0; i < MAX_CSI_REPORTCONFIG; i++) {
|
||||
if (mac->csi_report_template[i].reportConfigId == csi_reportconfig->reportConfigId) {
|
||||
csi_report = &mac->csi_report_template[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(csi_report, "Couldn't find CSI report with ID %ld\n", csi_reportconfig->reportConfigId);
|
||||
n_bits = nr_get_csi_bitlen(csi_report);
|
||||
int cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
|
||||
int rsrp_bitlen = csi_report->CSI_report_bitlen.rsrp_bitlen;
|
||||
int diff_rsrp_bitlen = csi_report->CSI_report_bitlen.diff_rsrp_bitlen;
|
||||
@@ -2875,9 +2777,9 @@ uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pucch->csi_part1_payload = temp_payload;
|
||||
return n_bits;
|
||||
AssertFatal(n_bits <= 32, "Not supporting CSI report with more than 32 bits\n");
|
||||
csi_payload_t csi = {.part1_payload = temp_payload, .p1_bits = n_bits, csi.p2_bits = 0};
|
||||
return csi;
|
||||
}
|
||||
|
||||
// returns index from RSRP
|
||||
@@ -4027,6 +3929,7 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
|
||||
&tda_info,
|
||||
&pdu->pusch_config_pdu,
|
||||
NULL,
|
||||
NULL,
|
||||
&rar_grant,
|
||||
rnti,
|
||||
NR_SearchSpace__searchSpaceType_PR_common,
|
||||
|
||||
@@ -515,6 +515,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
NR_tda_info_t *tda_info,
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
|
||||
dci_pdu_rel15_t *dci,
|
||||
csi_payload_t *csi_report,
|
||||
RAR_grant_t *rar_grant,
|
||||
uint16_t rnti,
|
||||
int ss_type,
|
||||
@@ -631,6 +632,36 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
pusch_config_pdu->tbslbrm = 0;
|
||||
|
||||
} else if (dci) {
|
||||
pusch_config_pdu->ulsch_indicator = dci->ulsch_indicator;
|
||||
if (dci->csi_request.nbits > 0 && dci->csi_request.val > 0) {
|
||||
AssertFatal(csi_report, "CSI report needs to be present in case of CSI request\n");
|
||||
pusch_config_pdu->pusch_uci.csi_part1_bit_length = csi_report->p1_bits;
|
||||
pusch_config_pdu->pusch_uci.csi_part1_payload = csi_report->part1_payload;
|
||||
pusch_config_pdu->pusch_uci.csi_part2_bit_length = csi_report->p2_bits;
|
||||
pusch_config_pdu->pusch_uci.csi_part2_payload = csi_report->part2_payload;
|
||||
AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH, "UCI on PUSCH need to be configured\n");
|
||||
NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup;
|
||||
AssertFatal(onPusch &&
|
||||
onPusch->betaOffsets &&
|
||||
onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic,
|
||||
"Only semistatic beta offset is supported\n");
|
||||
NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic;
|
||||
|
||||
pusch_config_pdu->pusch_uci.beta_offset_csi1 = pusch_config_pdu->pusch_uci.csi_part1_bit_length < 12 ?
|
||||
*beta_offsets->betaOffsetCSI_Part1_Index1 :
|
||||
*beta_offsets->betaOffsetCSI_Part1_Index2;
|
||||
pusch_config_pdu->pusch_uci.beta_offset_csi2 = pusch_config_pdu->pusch_uci.csi_part2_bit_length < 12 ?
|
||||
*beta_offsets->betaOffsetCSI_Part2_Index1 :
|
||||
*beta_offsets->betaOffsetCSI_Part2_Index2;
|
||||
pusch_config_pdu->pusch_uci.alpha_scaling = onPusch->scaling;
|
||||
}
|
||||
else {
|
||||
pusch_config_pdu->pusch_uci.csi_part1_bit_length = 0;
|
||||
pusch_config_pdu->pusch_uci.csi_part2_bit_length = 0;
|
||||
}
|
||||
|
||||
pusch_config_pdu->pusch_uci.harq_ack_bit_length = 0;
|
||||
|
||||
pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart;
|
||||
pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize;
|
||||
|
||||
@@ -891,6 +922,47 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
return 0;
|
||||
}
|
||||
|
||||
csi_payload_t nr_ue_aperiodic_csi_reporting(NR_UE_MAC_INST_t *mac, dci_field_t csi_request, int tda, long *k2)
|
||||
{
|
||||
NR_CSI_AperiodicTriggerStateList_t *aperiodicTriggerStateList = mac->sc_info.aperiodicTriggerStateList;
|
||||
AssertFatal(aperiodicTriggerStateList, "Received CSI request via DCI but aperiodicTriggerStateList is not present\n");
|
||||
int n_states = aperiodicTriggerStateList->list.count;
|
||||
int n_ts = csi_request.nbits;
|
||||
csi_payload_t csi = {0};
|
||||
AssertFatal(n_states <= ((1 << n_ts) - 1), "Case of subselection indication of trigger states not supported yet\n");
|
||||
int num_trig = 0;
|
||||
for (int i = 0; i < n_ts; i++) {
|
||||
// A non-zero codepoint of the CSI request field in the DCI is mapped to a CSI triggering state
|
||||
// according to the order of the associated positions of the up to (2^n_ts -1) trigger states
|
||||
// in CSI-AperiodicTriggerStateList with codepoint 1 mapped to the triggering state in the first position
|
||||
if (csi_request.val & (1 << i)) {
|
||||
AssertFatal(num_trig == 0, "Multiplexing more than 1 CSI report is not supported\n");
|
||||
NR_CSI_AperiodicTriggerState_t *trigger_state = aperiodicTriggerStateList->list.array[i];
|
||||
AssertFatal(trigger_state->associatedReportConfigInfoList.list.count == 1,
|
||||
"Cannot handle more than 1 report configuration per state\n");
|
||||
NR_CSI_AssociatedReportConfigInfo_t *reportconfig = trigger_state->associatedReportConfigInfoList.list.array[0];
|
||||
NR_CSI_ReportConfigId_t id = reportconfig->reportConfigId;
|
||||
NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig;
|
||||
int found = -1;
|
||||
for (int c = 0; c < csi_measconfig->csi_ReportConfigToAddModList->list.count; c++) {
|
||||
NR_CSI_ReportConfig_t *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[c];
|
||||
if (report_config->reportConfigId == id) {
|
||||
struct NR_CSI_ReportConfig__reportConfigType__aperiodic__reportSlotOffsetList *offset_list = &report_config->reportConfigType.choice.aperiodic->reportSlotOffsetList;
|
||||
AssertFatal(tda < offset_list->list.count, "TDA index from DCI %d exceeds slot offset list %d\n", tda, offset_list->list.count);
|
||||
if (k2 == NULL || *k2 < *offset_list->list.array[tda])
|
||||
k2 = offset_list->list.array[tda];
|
||||
found = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(found >= 0, "Couldn't find csi-ReportConfig with ID %ld\n", id);
|
||||
num_trig++;
|
||||
csi = nr_get_csi_payload(mac, found, ON_PUSCH, csi_measconfig);
|
||||
}
|
||||
}
|
||||
return csi;
|
||||
}
|
||||
|
||||
int configure_srs_pdu(NR_UE_MAC_INST_t *mac,
|
||||
NR_SRS_Resource_t *srs_resource,
|
||||
fapi_nr_ul_config_srs_pdu *srs_config_pdu,
|
||||
@@ -1347,6 +1419,10 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
|
||||
ulcfg_pdu++;
|
||||
}
|
||||
release_ul_config(ulcfg_pdu, false);
|
||||
|
||||
if(mac->state >= UE_PERFORMING_RA && mac->state < UE_DETACHING)
|
||||
nr_ue_pucch_scheduler(mac, frame_tx, slot_tx);
|
||||
|
||||
if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) {
|
||||
LOG_D(NR_MAC, "3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx);
|
||||
nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slot_tx,
|
||||
@@ -1385,9 +1461,6 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
|
||||
nr_timer_start(&sched_info->Bj_timer);
|
||||
}
|
||||
}
|
||||
|
||||
if(mac->state >= UE_PERFORMING_RA && mac->state < UE_DETACHING)
|
||||
nr_ue_pucch_scheduler(mac, frame_tx, slot_tx, ul_info->phy_data);
|
||||
}
|
||||
|
||||
static uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size, int value)
|
||||
@@ -2008,7 +2081,102 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac)
|
||||
LOG_D(NR_MAC,"Map SSB to RO done\n");
|
||||
}
|
||||
|
||||
void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, void *phy_data)
|
||||
static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, const PUCCH_sched_t *pucch)
|
||||
{
|
||||
fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = lockGet_ul_iterator(mac, frame_tx, slot_tx);
|
||||
if (!ulcfg_pdu)
|
||||
return NULL;
|
||||
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_pdu = NULL;
|
||||
while (ulcfg_pdu->pdu_type != FAPI_NR_END) {
|
||||
if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) {
|
||||
int start_pusch = ulcfg_pdu->pusch_config_pdu.start_symbol_index;
|
||||
int nsymb_pusch = ulcfg_pdu->pusch_config_pdu.nr_of_symbols;
|
||||
int end_pusch = start_pusch + nsymb_pusch;
|
||||
NR_PUCCH_Resource_t *pucchres = pucch->pucch_resource;
|
||||
int nr_of_symbols = 0;
|
||||
int start_symbol_index = 0;
|
||||
switch(pucchres->format.present) {
|
||||
case NR_PUCCH_Resource__format_PR_format0 :
|
||||
nr_of_symbols = pucchres->format.choice.format0->nrofSymbols;
|
||||
start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format1 :
|
||||
nr_of_symbols = pucchres->format.choice.format1->nrofSymbols;
|
||||
start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format2 :
|
||||
nr_of_symbols = pucchres->format.choice.format2->nrofSymbols;
|
||||
start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format3 :
|
||||
nr_of_symbols = pucchres->format.choice.format3->nrofSymbols;
|
||||
start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format4 :
|
||||
nr_of_symbols = pucchres->format.choice.format4->nrofSymbols;
|
||||
start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex;
|
||||
break;
|
||||
default :
|
||||
AssertFatal(false, "Undefined PUCCH format \n");
|
||||
}
|
||||
int final_symbol = nr_of_symbols + start_symbol_index;
|
||||
// PUCCH overlapping in time with PUSCH
|
||||
if (start_symbol_index < end_pusch && final_symbol > start_pusch) {
|
||||
pusch_pdu = &ulcfg_pdu->pusch_config_pdu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ulcfg_pdu++;
|
||||
}
|
||||
|
||||
if (!pusch_pdu) {
|
||||
release_ul_config(ulcfg_pdu, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a UE would transmit on a serving cell a PUSCH without UL-SCH that overlaps with a PUCCH transmission
|
||||
// on a serving cell that includes positive SR information, the UE does not transmit the PUSCH.
|
||||
if (pusch_pdu && pusch_pdu->ulsch_indicator == 0 && pucch->sr_payload == 1) {
|
||||
release_ul_config(ulcfg_pdu, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// - UE multiplexes only HARQ-ACK information, if any, from the UCI in the PUSCH transmission
|
||||
// and does not transmit the PUCCH if the UE multiplexes aperiodic or semi-persistent CSI reports in the PUSCH
|
||||
|
||||
// - UE multiplexes only HARQ-ACK information and CSI reports, if any, from the UCI in the PUSCH transmission
|
||||
// and does not transmit the PUCCH if the UE does not multiplex aperiodic or semi-persistent CSI reports in the PUSCH
|
||||
bool mux_done = false;
|
||||
if (pucch->n_harq > 0) {
|
||||
pusch_pdu->pusch_uci.harq_ack_bit_length = pucch->n_harq;
|
||||
pusch_pdu->pusch_uci.harq_payload = pucch->ack_payload;
|
||||
NR_PUSCH_Config_t *pusch_Config = mac->current_UL_BWP->pusch_Config;
|
||||
AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH, "UCI on PUSCH need to be configured\n");
|
||||
NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup;
|
||||
AssertFatal(onPusch &&
|
||||
onPusch->betaOffsets &&
|
||||
onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic,
|
||||
"Only semistatic beta offset is supported\n");
|
||||
NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic;
|
||||
pusch_pdu->pusch_uci.beta_offset_harq_ack = pucch->n_harq > 2 ?
|
||||
(pucch->n_harq < 12 ? *beta_offsets->betaOffsetACK_Index2 :
|
||||
*beta_offsets->betaOffsetACK_Index3) :
|
||||
*beta_offsets->betaOffsetACK_Index1;
|
||||
pusch_pdu->pusch_uci.alpha_scaling = onPusch->scaling;
|
||||
mux_done = true;
|
||||
}
|
||||
if (pusch_pdu->pusch_uci.csi_part1_bit_length == 0 && pusch_pdu->pusch_uci.csi_part2_bit_length == 0) {
|
||||
// To support this we would need to shift some bits into CSI part2 -> need to change the logic
|
||||
AssertFatal(pucch->n_csi == 0, "Multiplexing periodic CSI on PUSCH not supported\n");
|
||||
}
|
||||
|
||||
release_ul_config(ulcfg_pdu, false);
|
||||
// only use PUSCH if any mux is done otherwise send PUCCH
|
||||
return mux_done;
|
||||
}
|
||||
|
||||
void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP)
|
||||
{
|
||||
PUCCH_sched_t pucch[3] = {0}; // TODO the size might change in the future in case of multiple SR or multiple CSI in a slot
|
||||
|
||||
@@ -2044,6 +2212,7 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi
|
||||
|
||||
if (num_res > 1)
|
||||
multiplex_pucch_resource(mac, pucch, num_res);
|
||||
|
||||
for (int j = 0; j < num_res; j++) {
|
||||
if (pucch[j].n_harq + pucch[j].n_sr + pucch[j].n_csi != 0) {
|
||||
LOG_D(NR_MAC,
|
||||
@@ -2056,6 +2225,11 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi
|
||||
mac->nr_ue_emul_l1.num_srs = pucch[j].n_sr;
|
||||
mac->nr_ue_emul_l1.num_harqs = pucch[j].n_harq;
|
||||
mac->nr_ue_emul_l1.num_csi_reports = pucch[j].n_csi;
|
||||
|
||||
// checking if we need to schedule pucch[j] on PUSCH
|
||||
if (schedule_uci_on_pusch(mac, frameP, slotP, &pucch[j]))
|
||||
continue;
|
||||
|
||||
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
|
||||
if (!pdu) {
|
||||
LOG_E(NR_MAC, "Error in pucch allocation\n");
|
||||
@@ -2064,6 +2238,7 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi
|
||||
mac->nr_ue_emul_l1.active_uci_sfn_slot = NFAPI_SFNSLOT2HEX(frameP, slotP);
|
||||
int ret = nr_ue_configure_pucch(mac,
|
||||
slotP,
|
||||
frameP,
|
||||
mac->crnti, // FIXME not sure this is valid for all pucch instances
|
||||
&pucch[j],
|
||||
&pdu->pucch_config_pdu);
|
||||
@@ -2071,14 +2246,6 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi
|
||||
remove_ul_config_last_item(pdu);
|
||||
release_ul_config(pdu, false);
|
||||
}
|
||||
if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) {
|
||||
nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slotP,
|
||||
.mac = mac,
|
||||
.module_id = mac->ue_id,
|
||||
.CC_id = 0 /*TBR fix*/,
|
||||
.phy_data = phy_data};
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2185,7 +2352,7 @@ uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, NR_CSI
|
||||
if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations)
|
||||
return meas_bitmap; // CSI-RS for tracking
|
||||
for(int i = 0; i < csi_measconfig->csi_ReportConfigToAddModList->list.count; i++) {
|
||||
struct NR_CSI_ReportConfig *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[i];
|
||||
NR_CSI_ReportConfig_t *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[i];
|
||||
if(report_config->resourcesForChannelMeasurement != csi_res_id)
|
||||
continue;
|
||||
// bit 0 RSRP bit 1 RI bit 2 LI bit 3 PMI bit 4 CQI bit 5 i1
|
||||
|
||||
@@ -273,7 +273,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
curr_pucch->frame = sched_frame;
|
||||
curr_pucch->ul_slot = sched_slot;
|
||||
curr_pucch->resource_indicator = res_index;
|
||||
curr_pucch->csi_bits += nr_get_csi_bitlen(UE->csi_report_template, csi_report_id);
|
||||
curr_pucch->csi_bits += nr_get_csi_bitlen(&UE->csi_report_template[csi_report_id]);
|
||||
curr_pucch->active = true;
|
||||
|
||||
int bwp_start = ul_bwp->BWPStart;
|
||||
|
||||
@@ -60,9 +60,6 @@ static int nr_pdcp_current_time_last_subframe;
|
||||
hash_table_t *pdcp_coll_p;
|
||||
static uint64_t pdcp_optmask;
|
||||
|
||||
uint8_t first_dcch = 0;
|
||||
uint8_t proto_agent_flag = 0;
|
||||
|
||||
static ngran_node_t node_type;
|
||||
|
||||
nr_pdcp_entity_t *nr_pdcp_get_rb(nr_pdcp_ue_t *ue, int rb_id, bool srb_flag)
|
||||
|
||||
@@ -31,14 +31,5 @@
|
||||
#endif
|
||||
|
||||
|
||||
unsigned int mac_debug;
|
||||
|
||||
//MAC_xface *mac_xface;
|
||||
|
||||
//MACPHY_PARAMS MACPHY_params;
|
||||
|
||||
unsigned int mac_registered;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -53,8 +53,6 @@
|
||||
#include "openair3/SECU/nas_stream_eia2.h"
|
||||
#include "openair3/UTILS/conversions.h"
|
||||
|
||||
uint8_t *registration_request_buf;
|
||||
uint32_t registration_request_len;
|
||||
extern char *baseNetAddress;
|
||||
extern uint16_t NB_UE_INST;
|
||||
static nr_ue_nas_t nr_ue_nas = {0};
|
||||
@@ -474,10 +472,10 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
|
||||
|
||||
// encode the message
|
||||
initialNasMsg->data = malloc16_clear(size * sizeof(Byte_t));
|
||||
registration_request_buf = initialNasMsg->data;
|
||||
nas->registration_request_buf = initialNasMsg->data;
|
||||
|
||||
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
|
||||
registration_request_len = initialNasMsg->length;
|
||||
nas->registration_request_len = initialNasMsg->length;
|
||||
|
||||
}
|
||||
|
||||
@@ -591,9 +589,9 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
|
||||
|
||||
size += fill_imeisv(&mm_msg->fgs_security_mode_complete.fgsmobileidentity, nas->uicc);
|
||||
|
||||
mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.value = registration_request_buf;
|
||||
mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.length = registration_request_len;
|
||||
size += (registration_request_len + 2);
|
||||
mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.value = nas->registration_request_buf;
|
||||
mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.length = nas->registration_request_len;
|
||||
size += (nas->registration_request_len + 2);
|
||||
|
||||
// encode the message
|
||||
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
|
||||
|
||||
@@ -102,6 +102,8 @@ typedef struct {
|
||||
stream_security_container_t *security_container;
|
||||
Guti5GSMobileIdentity_t *guti;
|
||||
bool termination_procedure;
|
||||
uint8_t *registration_request_buf;
|
||||
uint32_t registration_request_len;
|
||||
} nr_ue_nas_t;
|
||||
|
||||
typedef enum fgs_protocol_discriminator_e {
|
||||
|
||||
+30
-2
@@ -768,6 +768,8 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
|
||||
s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate);
|
||||
*ptimestamp = s->rx_timestamp;
|
||||
|
||||
T(T_USRP_RX_ANT0, T_INT(s->rx_timestamp), T_BUFFER(buff[0], samples_received*4));
|
||||
|
||||
recplay_state_t *recPlay=device->recplay_state;
|
||||
|
||||
if (device->openair0_cfg->recplay_mode == RECPLAY_RECORDMODE) { // record mode
|
||||
@@ -1012,6 +1014,28 @@ int trx_usrp_reset_stats(openair0_device *device) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*! \brief synch the USRP time accross devices using the host clock (ideally syched with PTP, but also NTP works) and assuming all
|
||||
* devices are synched by octoclock */
|
||||
static void usrp_sync_pps(usrp_state_t *s)
|
||||
{
|
||||
// First, wait for PPS.
|
||||
uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps();
|
||||
|
||||
while (time_last_pps == s->usrp->get_time_last_pps()) {
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
||||
}
|
||||
|
||||
// get host time
|
||||
struct timespec tp;
|
||||
if (clock_gettime(CLOCK_TAI, &tp) != 0)
|
||||
LOG_W(PHY, "error getting system time\n");
|
||||
double tai_sec = (double)tp.tv_sec;
|
||||
|
||||
// set USRP time to host time at next pps
|
||||
s->usrp->set_time_next_pps(uhd::time_spec_t(tai_sec));
|
||||
LOG_I(HW, "USRP clock set to %f sec\n", tai_sec);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
LOG_I(HW, "openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs);
|
||||
@@ -1188,8 +1212,12 @@ extern "C" {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
s->usrp->set_time_next_pps(uhd::time_spec_t(0.0));
|
||||
|
||||
if (s->usrp->get_time_source(0) == "external") {
|
||||
usrp_sync_pps(s);
|
||||
} else {
|
||||
s->usrp->set_time_next_pps(uhd::time_spec_t(0.0));
|
||||
}
|
||||
|
||||
if (s->usrp->get_clock_source(0) == "external") {
|
||||
if (check_ref_locked(s,0)) {
|
||||
LOG_I(HW,"USRP locked to external reference!\n");
|
||||
|
||||
Reference in New Issue
Block a user