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:
Robert Schmidt
2024-06-06 12:55:36 +00:00
40 changed files with 1256 additions and 501 deletions
+9
View File
@@ -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
View File
@@ -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
+91
View File
@@ -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
################################################
+1
View File
@@ -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)
+153
View File
@@ -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/
```
+19
View File
@@ -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
View File
@@ -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 { \
+44
View File
@@ -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__ */
+34
View File
@@ -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"
+54
View File
@@ -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>
+5
View File
@@ -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;
-3
View File
@@ -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;
+11 -11
View File
@@ -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;
-1
View File
@@ -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);
-19
View File
@@ -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;
}
}
-2
View File
@@ -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 */
+3 -2
View File
@@ -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) {
+2
View File
@@ -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;
+11 -10
View File
@@ -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);
+137 -125
View File
@@ -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);
}
}
+16 -2
View File
@@ -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;
/*@}*/
+25 -27
View File
@@ -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,
+2
View File
@@ -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)
+1 -2
View File
@@ -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;
}
+131 -228
View File
@@ -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,
+180 -13
View File
@@ -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
+5 -7
View File
@@ -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));
+2
View File
@@ -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
View File
@@ -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");