Commit 6d9c2c35 authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2025_w07' into 'develop'

Integration: `2025.w07`

Closes #812, #901, #904, #881, and #819

See merge request oai/openairinterface5g!3258

* !3055 Dynamic PDCCH aggregation level
* !3176 Refactor and extend NAS Registration Request
* !3256 Add check on force_local in custom_command CI handling
* !3257 Bugfix in gNB modulated DCI buffer size
* !3249 Improvements in TDD configuration
* !3194 fix NTN LEO scenarios
* !3200 FHI72: remove polling, fix memory leak
* !3127 Optimizations of PDSCH Resource Mapping in nr_dlsch.c/nr_modulation.c
* !3252 \[E2 agent\] Multi RC REPORT service styles support
parents ff58b5e1 87c83f72
...@@ -1366,6 +1366,7 @@ target_link_libraries(NR_L2_UE PRIVATE nr_nas) ...@@ -1366,6 +1366,7 @@ target_link_libraries(NR_L2_UE PRIVATE nr_nas)
add_library(MAC_NR_COMMON add_library(MAC_NR_COMMON
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
) )
target_link_libraries(MAC_NR_COMMON PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) target_link_libraries(MAC_NR_COMMON PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
...@@ -1891,6 +1892,7 @@ add_executable(nr-uesoftmodem ...@@ -1891,6 +1892,7 @@ add_executable(nr-uesoftmodem
${OPENAIR_DIR}/radio/COMMON/common_lib.c ${OPENAIR_DIR}/radio/COMMON/common_lib.c
${OPENAIR_DIR}/radio/COMMON/record_player.c ${OPENAIR_DIR}/radio/COMMON/record_player.c
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c ${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
) )
......
...@@ -18,7 +18,8 @@ gNBs = ...@@ -18,7 +18,8 @@ gNBs =
sib1_tda = 5; sib1_tda = 5;
min_rxtxtime = 6; min_rxtxtime = 6;
disable_harq = 1; num_dlharq = 32;
num_ulharq = 32;
servingCellConfigCommon = ( servingCellConfigCommon = (
{ {
...@@ -28,11 +29,11 @@ gNBs = ...@@ -28,11 +29,11 @@ gNBs =
# downlinkConfigCommon # downlinkConfigCommon
#frequencyInfoDL #frequencyInfoDL
# this is 2150.43 MHz + 14 PRBs@15kHz SCS (same as initial BWP), points to Subcarrier 0 of RB#10 of SSB block # GSCN 6221
absoluteFrequencySSB = 430590; absoluteFrequencySSB = 497770;
dl_frequencyBand = 66; dl_frequencyBand = 254;
# this is 2150.43 MHz # this is 2486.15 MHz
dl_absoluteFrequencyPointA = 430086; dl_absoluteFrequencyPointA = 497230;
#scs-SpecificCarrierList #scs-SpecificCarrierList
dl_offstToCarrier = 0; dl_offstToCarrier = 0;
# subcarrierSpacing # subcarrierSpacing
...@@ -52,9 +53,9 @@ gNBs = ...@@ -52,9 +53,9 @@ gNBs =
#uplinkConfigCommon #uplinkConfigCommon
#frequencyInfoUL #frequencyInfoUL
ul_frequencyBand = 66; ul_frequencyBand = 254;
# this is 1750.43 MHz # this is 1612.65 MHz
ul_absoluteFrequencyPointA = 350086; ul_absoluteFrequencyPointA = 322530;
#scs-SpecificCarrierList #scs-SpecificCarrierList
ul_offstToCarrier = 0; ul_offstToCarrier = 0;
# subcarrierSpacing # subcarrierSpacing
...@@ -147,14 +148,15 @@ gNBs = ...@@ -147,14 +148,15 @@ gNBs =
#ext2 #ext2
#ntn_Config_r17 #ntn_Config_r17
cellSpecificKoffset_r17 = 478; cellSpecificKoffset_r17 = 40;
ta-Common-r17 = 29314900; ta-Common-r17 = 4634000; # 18.87 ms
ta-CommonDrift-r17 = -230000; # -46 µs/s
positionX-r17 = 0; positionX-r17 = 0;
positionY-r17 = 0; positionY-r17 = -2166908; # -2816980.4 m
positionZ-r17 = 32433846; positionZ-r17 = 4910784; # 6384019.2 m
velocityVX-r17 = 0; velocityVX-r17 = 0;
velocityVY-r17 = 0; velocityVY-r17 = 115246; # 6914.76 m/s
velocityVZ-r17 = 0; velocityVZ-r17 = 50853; # 3051.18 m/s
} }
); );
...@@ -196,8 +198,11 @@ MACRLCs = ( ...@@ -196,8 +198,11 @@ MACRLCs = (
num_cc = 1; num_cc = 1;
tr_s_preference = "local_L1"; tr_s_preference = "local_L1";
tr_n_preference = "local_RRC"; tr_n_preference = "local_RRC";
# ulsch_max_frame_inactivity = 0;
pusch_TargetSNRx10 = 150; pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200;
dl_max_mcs = 9;
ul_max_mcs = 9;
} }
); );
...@@ -205,7 +210,7 @@ L1s = ( ...@@ -205,7 +210,7 @@ L1s = (
{ {
num_cc = 1; num_cc = 1;
tr_n_preference = "local_mac"; tr_n_preference = "local_mac";
prach_dtx_threshold = 120; prach_dtx_threshold = 150;
pucch0_dtx_threshold = 150; pucch0_dtx_threshold = 150;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
} }
...@@ -243,11 +248,28 @@ rfsimulator : ...@@ -243,11 +248,28 @@ rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = 4043; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = ("chanmod"); #("saviq"); or/and "chanmod"
modelname = "AWGN"; prop_delay = 20;
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
}; };
channelmod = {
max_chan=10;
modellist="modellist_rfsimu_1";
modellist_rfsimu_1 = (
{
model_name = "rfsimu_channel_enB0"
type = "SAT_LEO_TRANS";
noise_power_dB = -100;
},
{
model_name = "rfsimu_channel_ue0"
type = "SAT_LEO_TRANS";
noise_power_dB = -100;
}
);
};
security = { security = {
# preferred ciphering algorithms # preferred ciphering algorithms
# the first one of the list that an UE supports in chosen # the first one of the list that an UE supports in chosen
...@@ -277,4 +299,3 @@ log_config : ...@@ -277,4 +299,3 @@ log_config :
ngap_log_level ="debug"; ngap_log_level ="debug";
f1ap_log_level ="debug"; f1ap_log_level ="debug";
}; };
...@@ -28,11 +28,11 @@ gNBs = ...@@ -28,11 +28,11 @@ gNBs =
# downlinkConfigCommon # downlinkConfigCommon
#frequencyInfoDL #frequencyInfoDL
# GSCN 6221 = 497770, (GSCN 6215 - 497290) # GSCN 6221
absoluteFrequencySSB = 497770; absoluteFrequencySSB = 497770;
dl_frequencyBand = 254; dl_frequencyBand = 254;
# this is 2486.9 MHz # this is 2486.15 MHz
dl_absoluteFrequencyPointA = 497380; dl_absoluteFrequencyPointA = 497230;
#scs-SpecificCarrierList #scs-SpecificCarrierList
dl_offstToCarrier = 0; dl_offstToCarrier = 0;
# subcarrierSpacing # subcarrierSpacing
...@@ -47,14 +47,14 @@ gNBs = ...@@ -47,14 +47,14 @@ gNBs =
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 0; initialDLBWPsubcarrierSpacing = 0;
#pdcch-ConfigCommon #pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 0; initialDLBWPcontrolResourceSetZero = 2;
initialDLBWPsearchSpaceZero = 0; initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon #uplinkConfigCommon
#frequencyInfoUL #frequencyInfoUL
ul_frequencyBand = 254; ul_frequencyBand = 254;
# this is 1613.4 MHz # this is 1612.65 MHz
ul_absoluteFrequencyPointA = 322680; ul_absoluteFrequencyPointA = 322530;
#scs-SpecificCarrierList #scs-SpecificCarrierList
ul_offstToCarrier = 0; ul_offstToCarrier = 0;
# subcarrierSpacing # subcarrierSpacing
...@@ -147,8 +147,8 @@ gNBs = ...@@ -147,8 +147,8 @@ gNBs =
#ext2 #ext2
#ntn_Config_r17 #ntn_Config_r17
cellSpecificKoffset_r17 = 478; //GEO cellSpecificKoffset_r17 = 478;
ta-Common-r17 = 29319745; ta-Common-r17 = 58629666; # 238.74 ms
positionX-r17 = 0; positionX-r17 = 0;
positionY-r17 = 0; positionY-r17 = 0;
positionZ-r17 = 32433846; positionZ-r17 = 32433846;
...@@ -196,8 +196,11 @@ MACRLCs = ( ...@@ -196,8 +196,11 @@ MACRLCs = (
num_cc = 1; num_cc = 1;
tr_s_preference = "local_L1"; tr_s_preference = "local_L1";
tr_n_preference = "local_RRC"; tr_n_preference = "local_RRC";
# ulsch_max_frame_inactivity = 0;
pusch_TargetSNRx10 = 150; pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200;
dl_max_mcs = 9;
ul_max_mcs = 9;
} }
); );
...@@ -205,7 +208,7 @@ L1s = ( ...@@ -205,7 +208,7 @@ L1s = (
{ {
num_cc = 1; num_cc = 1;
tr_n_preference = "local_mac"; tr_n_preference = "local_mac";
prach_dtx_threshold = 120; prach_dtx_threshold = 150;
pucch0_dtx_threshold = 150; pucch0_dtx_threshold = 150;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
} }
...@@ -244,7 +247,7 @@ rfsimulator : ...@@ -244,7 +247,7 @@ rfsimulator :
serveraddr = "server"; serveraddr = "server";
serverport = 4043; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; prop_delay = 238.74;
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
}; };
...@@ -277,4 +280,3 @@ log_config : ...@@ -277,4 +280,3 @@ log_config :
ngap_log_level ="debug"; ngap_log_level ="debug";
f1ap_log_level ="debug"; f1ap_log_level ="debug";
}; };
...@@ -406,6 +406,9 @@ def ExecuteActionWithParam(action): ...@@ -406,6 +406,9 @@ def ExecuteActionWithParam(action):
elif action == 'Custom_Command': elif action == 'Custom_Command':
node = test.findtext('node') node = test.findtext('node')
if force_local:
# Change all execution targets to localhost
node = 'localhost'
command = test.findtext('command') command = test.findtext('command')
command_fail = test.findtext('command_fail') in ['True', 'true', 'Yes', 'yes'] command_fail = test.findtext('command_fail') in ['True', 'true', 'Yes', 'yes']
success = cls_oaicitest.Custom_Command(HTML, node, command, command_fail) success = cls_oaicitest.Custom_Command(HTML, node, command, command_fail)
......
...@@ -86,7 +86,7 @@ services: ...@@ -86,7 +86,7 @@ services:
cap_drop: cap_drop:
- ALL - ALL
environment: environment:
USE_ADDITIONAL_OPTIONS: --rfsim --rfsimulator.prop_delay 238.74 --log_config.global_log_options level,nocolor,time USE_ADDITIONAL_OPTIONS: --rfsim --log_config.global_log_options level,nocolor,time
ASAN_OPTIONS: detect_leaks=0 ASAN_OPTIONS: detect_leaks=0
depends_on: depends_on:
- oai-ext-dn - oai-ext-dn
...@@ -94,7 +94,7 @@ services: ...@@ -94,7 +94,7 @@ services:
public_net: public_net:
ipv4_address: 192.168.71.140 ipv4_address: 192.168.71.140
volumes: volumes:
- ../../conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf - ../../conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck: healthcheck:
test: /bin/bash -c "pgrep nr-softmodem" test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s interval: 10s
...@@ -110,7 +110,7 @@ services: ...@@ -110,7 +110,7 @@ services:
- NET_ADMIN # for interface bringup - NET_ADMIN # for interface bringup
- NET_RAW # for ping - NET_RAW # for ping
environment: environment:
USE_ADDITIONAL_OPTIONS: --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 238.74 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time USE_ADDITIONAL_OPTIONS: --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 238.74 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on: depends_on:
- oai-gnb - oai-gnb
networks: networks:
......
...@@ -150,6 +150,15 @@ typedef enum ip_traffic_type_e { ...@@ -150,6 +150,15 @@ typedef enum ip_traffic_type_e {
TRAFFIC_PC5S_SESSION_INIT = 10 TRAFFIC_PC5S_SESSION_INIT = 10
} ip_traffic_type_t; } ip_traffic_type_t;
typedef enum {
PDCCH_AGG_LEVEL1 = 0,
PDCCH_AGG_LEVEL2,
PDCCH_AGG_LEVEL4,
PDCCH_AGG_LEVEL8,
PDCCH_AGG_LEVEL16,
NUM_PDCCH_AGG_LEVELS
} Pdcch_Aggregation_Level_t;
typedef struct net_ip_address_s { typedef struct net_ip_address_s {
unsigned ipv4: 1; unsigned ipv4: 1;
unsigned ipv6: 1; unsigned ipv6: 1;
......
...@@ -551,6 +551,18 @@ void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { ...@@ -551,6 +551,18 @@ void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) {
*n_rb = 6*count; *n_rb = 6*count;
} }
// According to 38.211 7.3.2.2
int get_coreset_num_cces(uint8_t *FreqDomainResource, int duration)
{
int num_rbs;
int rb_offset;
get_coreset_rballoc(FreqDomainResource, &num_rbs, &rb_offset);
int total_resource_element_groups = num_rbs * duration;
int reg_per_cce = 6;
int total_cces = total_resource_element_groups / reg_per_cce;
return total_cces;
}
int get_nb_periods_per_frame(uint8_t tdd_period) int get_nb_periods_per_frame(uint8_t tdd_period)
{ {
......
...@@ -142,7 +142,7 @@ typedef struct frame_structure_s { ...@@ -142,7 +142,7 @@ typedef struct frame_structure_s {
int8_t numb_slots_frame; int8_t numb_slots_frame;
int8_t numb_slots_period; int8_t numb_slots_period;
int8_t numb_period_frame; int8_t numb_period_frame;
bool is_tdd; frame_type_t frame_type;
} frame_structure_t; } frame_structure_t;
typedef struct { typedef struct {
...@@ -245,6 +245,7 @@ uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, ui ...@@ -245,6 +245,7 @@ uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, ui
int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs); int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs);
int get_SLIV(uint8_t S, uint8_t L); int get_SLIV(uint8_t S, uint8_t L);
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset); void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
int get_coreset_num_cces(uint8_t *FreqDomainResource, int duration);
int get_nr_table_idx(int nr_bandP, uint8_t scs_index); int get_nr_table_idx(int nr_bandP, uint8_t scs_index);
int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index); int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index);
frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index); frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#define NOTIFIED_FIFO_H #define NOTIFIED_FIFO_H
#include "pthread_utils.h" #include "pthread_utils.h"
#include <stdint.h> #include <stdint.h>
#include <malloc.h>
#include <pthread.h> #include <pthread.h>
#include "time_meas.h" #include "time_meas.h"
#include <memory.h> #include <memory.h>
......
...@@ -38,6 +38,33 @@ The actual scheduler implementation can be found in functions `pf_dl()` and ...@@ -38,6 +38,33 @@ The actual scheduler implementation can be found in functions `pf_dl()` and
[`gNB_scheduler_ulsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c) [`gNB_scheduler_ulsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c)
(for UL), respectively. (for UL), respectively.
## PDDCH aggregation level
PDCCH aggregation level is selected using closed loop controller, where DL HARQ
feedback is the controller feedback signal. It is used to increment `pdcch_cl_adjust`
variable if no feedback is detected and decrement the variable when feedback is detected.
`pdcch_cl_adjust` is later mapped to the PDCCH aggregation level range.
The value of `pdcch_cl_adjust` is clamped to range <0,1>, the increment value is 0.05 while
the decrement value is 0.01. These values are selected to ensure PDCCH success rate is high.
See Examples below for futher explaination.
The possible values of aggregation level on UE SS can be configured via `uess_agg_levels` configuration
option. By default the gNB uses only aggregation level 2 which translates to `uess_agg_levels` set to
`[0, 1, 0, 0, 0]`. For example, to enable aggregation level 2 and 4 set `uess_agg_levels` to `[0, 1, 1, 0, 0]`.
### Examples:
#### Example 1:
Say we have 90% PDCCH success rate at aggregation level 1, `pdcch_cl_adjust` will stay at 0
for most of the time. 2 consecutive PDCCH failures will not result in increasing the aggregation
level (because (0.05 + 0.05) * 4 = 0.4 which is closer to 0 than to 1). If PDCCH fails 3 times
in a row the aggregation level will change to 2 and hopefully back to 1 once more PDDCH successes
happen.
### Example 2
Say we have 0% PDCCH success rate (radio link failure scenario) but `pdcch_cl_adjust` is 0 indicating
perfect PDCCH channel. it would take ~18 PDCCH failures to reach maximum aggregation level.
# Periodic output and interpretation # Periodic output and interpretation
The scheduler periodically outputs statistics that can help you judge the radio The scheduler periodically outputs statistics that can help you judge the radio
......
...@@ -475,6 +475,19 @@ cmake .. -GNinja -DOAI_FHI72=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib ...@@ -475,6 +475,19 @@ cmake .. -GNinja -DOAI_FHI72=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib
ninja nr-softmodem oran_fhlib_5g params_libconfig ninja nr-softmodem oran_fhlib_5g params_libconfig
``` ```
Note that in tags 2025.w06 and prior, the FHI72 driver used polling to wait for
the next slot. This is inefficient as it burns CPU time, and has been replaced
with a more efficient mechanism. Nevertheless, if you experience problems that
did not occur previously, it is possible to re-enable polling, either with
`build_oai` like this
./build_oai --gNB --ninja -t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=$HOME/phy/fhi_lib/lib --cmake-opt -DOAI_FHI72_USE_POLLING=ON
or with `cmake` like so
cmake .. -GNinja -DOAI_FHI72=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib -DOAI_FHI72_USE_POLLING=ON
ninja oran_fhlib_5g
# Configuration # Configuration
RU and DU configurations have a circular dependency: you have to configure DU MAC address in the RU configuration and the RU MAC address, VLAN and Timing advance parameters in the DU configuration. RU and DU configurations have a circular dependency: you have to configure DU MAC address in the RU configuration and the RU MAC address, VLAN and Timing advance parameters in the DU configuration.
...@@ -1040,6 +1053,8 @@ In this case, you should reverify that `ptp4l` and `phc2sys` are working, e.g., ...@@ -1040,6 +1053,8 @@ In this case, you should reverify that `ptp4l` and `phc2sys` are working, e.g.,
do not do any jumps (during the last hour). While an occasional jump is not do not do any jumps (during the last hour). While an occasional jump is not
necessarily problematic for the gNB, many such messages mean that the system is necessarily problematic for the gNB, many such messages mean that the system is
not working, and UEs might not be able to attach or reach good performance. not working, and UEs might not be able to attach or reach good performance.
Also, you can try to compile with polling (see [the build
section](.#build-oai-gnb)) to see if it resolves the problem.
# Operation with multiple RUs # Operation with multiple RUs
......
...@@ -221,15 +221,49 @@ Or by providing this the the command line parameters: ...@@ -221,15 +221,49 @@ Or by providing this the the command line parameters:
### gNB ### gNB
The main parameter to cope with the large NTN propagation delay is the cellSpecificKoffset. The main parameters to cope with the large NTN propagation delay are cellSpecificKoffset, ta-Common, ta-CommonDrift and the ephemeris data (satellite position and velocity vectors).
This parameter is the scheduling offset used for the timing relationships that are modified for NTN (see TS 38.213).
The parameter `cellSpecificKoffset_r17` is the scheduling offset used for the timing relationships that are modified for NTN (see TS 38.213).
The unit of the field Koffset is number of slots for a given subcarrier spacing of 15 kHz. The unit of the field Koffset is number of slots for a given subcarrier spacing of 15 kHz.
This parameter can be provided to the gNB in the conf file as `cellSpecificKoffset_r17` in the section `servingCellConfigCommon`. The parameter `ta-Common-r17` is used to provide the propagation delay between the reference point (at the gNB) and the satellite.
The granularity of ta-Common is 4.072 × 10^(-3) µs. Values are given in unit of corresponding granularity.
The parameter `ta-CommonDrift-r17` indicates the drift rate of the common TA.
The granularity of ta-CommonDrift is 0.2 × 10^(-3) µs/s. Values are given in unit of corresponding granularity.
The satellite position and velocity vartors are provided using the following parameters:
`positionX-r17`, `positionY-r17`, `positionZ-r17`:
X, Y, Z coordinate of satellite position state vector in ECEF. Unit is meter.
Step of 1.3 m. Actual value = field value * 1.3.
`velocityVX-r17`, `velocityVY-r17`, `velocityVZ-r17`:
X, Y, Z coordinate of satellite velocity state vector in ECEF. Unit is meter/second.
Step of 0.06 m/s. Actual value = field value * 0.06.
These parameters can be provided to the gNB in the conf file in the section `servingCellConfigCommon`:
``` ```
... ...
cellSpecificKoffset_r17 = 478; # GEO satellite # GEO satellite
# cellSpecificKoffset_r17 = 40; # LEO satellite cellSpecificKoffset_r17 = 478;
ta-Common-r17 = 58629666; # 238.74 ms
positionX-r17 = 0;
positionY-r17 = 0;
positionZ-r17 = 32433846;
velocityVX-r17 = 0;
velocityVY-r17 = 0;
velocityVZ-r17 = 0;
# LEO satellite
# cellSpecificKoffset_r17 = 40;
# ta-Common-r17 = 4634000; # 18.87 ms
# ta-CommonDrift-r17 = -230000; # -46 µs/s
# positionX-r17 = 0;
# positionY-r17 = -2166908; # -2816980.4 m
# positionZ-r17 = 4910784; # 6384019.2 m
# velocityVX-r17 = 0;
# velocityVY-r17 = 115246; # 6914.76 m/s
# velocityVZ-r17 = 50853; # 3051.18 m/s
... ...
``` ```
...@@ -262,10 +296,11 @@ To enable this feature, the `disable_harq` flag has to be added to the gNB conf ...@@ -262,10 +296,11 @@ To enable this feature, the `disable_harq` flag has to be added to the gNB conf
... ...
``` ```
So with these modifications to the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf` an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this: The settings for a transparent GEO satellite scenario are already provided in the file `ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf`.
Using this conf file, an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this:
``` ```
cd cmake_targets cd cmake_targets
sudo ./ran_build/build/nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf --rfsim --rfsimulator.prop_delay 238.74 sudo ./ran_build/build/nr-softmodem -O ../ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf --rfsim
``` ```
To configure NTN gNB with 32 HARQ processes in downlink and uplink, add these settings in conf files under section `gNBs.[0]` To configure NTN gNB with 32 HARQ processes in downlink and uplink, add these settings in conf files under section `gNBs.[0]`
...@@ -281,32 +316,43 @@ To simulate a LEO satellite channel model with rfsimulator in UL (DL is simulate ...@@ -281,32 +316,43 @@ To simulate a LEO satellite channel model with rfsimulator in UL (DL is simulate
@include "channelmod_rfsimu_LEO_satellite.conf" @include "channelmod_rfsimu_LEO_satellite.conf"
``` ```
So with these modifications to the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf` an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, trasparent LEO satellite 5G NR NTN is this: The settings for a transparent LEO satellite scenario are already provided in the file `ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf`.
Using this conf file, an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, trasparent LEO satellite 5G NR NTN is this:
``` ```
cd cmake_targets cd cmake_targets
sudo ./ran_build/build/nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf --rfsim --rfsimulator.prop_delay 20 sudo ./ran_build/build/nr-softmodem -O ../ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf --rfsim
``` ```
### NR UE ### NR UE
At UE side, there are two main parameters to cope with the large NTN propagation delay, cellSpecificKoffset and ta-Common. At UE side, only few parameters have to be provided, as the UE receives most relevant parameters via SIB19 from the gNB.
`cellSpecificKoffset` is the same as for gNB and can be provided to the UE via command line parameter `--ntn-koffset`. But to calculate the UE specific TA, the UE position has to be provided in the `ue.conf` file.
`ta-Common` is a common timing advance and can be provided to the UE via command line parameter `--ntn-ta-common` in milliseconds. Also the LEO channel model has to be configured, e.g. by using an `@include` statement, just like on the gNB side:
```
...
position0 = {
x = 0.0;
y = 0.0;
z = 6377900.0;
}
@include "channelmod_rfsimu_LEO_satellite.conf"
```
So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this: So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this:
``` ```
cd cmake_targets cd cmake_targets
sudo ./ran_build/build/nr-uesoftmodem --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 238.74 --ntn-koffset 478 --ntn-ta-common 477.48 sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 238.74
``` ```
For LEO satellites a third parameter specifying the NTN propagation delay drift has ben added, ta-CommonDrift. For LEO satellite scenarios, the parameter `--ntn-initial-time-drift` must be provided via command line, as the UE needs this value to compensate for the time drift during initial sync, before SIB19 was received.
`ta-CommonDrift` provides the drift rate of the common timing advance and can be provided to the UE via command line parameter `--ntn-ta-commondrift` in microseconds per second. This parameter provides the drift rate of the complete DL timing (incl. feeder link and service link) in µs/s.
Also, to perform an autonomous TA update based on the DL drift, the boolean parameter `--autonomous-ta` should be added in case of a LEO satellite scenario. Also, to perform an autonomous TA update based on the DL drift, the boolean parameter `--autonomous-ta` should be added in case of a LEO satellite scenario.
So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent LEO satellite 5G NR NTN is this: So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent LEO satellite 5G NR NTN is this:
``` ```
cd cmake_targets cd cmake_targets
sudo ./ran_build/build/nr-uesoftmodem --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/channelmod_rfsimu_LEO_satellite.conf --time-sync-I 0.2 --ntn-koffset 40 --ntn-ta-common 37.74 --ntn-ta-commondrift -50 --autonomous-ta sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod --time-sync-I 0.1 --ntn-initial-time-drift -46 --autonomous-ta
``` ```
# Specific OAI modes # Specific OAI modes
......
...@@ -219,7 +219,6 @@ static void rx_func(processingData_L1_t *info) ...@@ -219,7 +219,6 @@ static void rx_func(processingData_L1_t *info)
gNB->if_inst->NR_UL_indication(&UL_INFO); gNB->if_inst->NR_UL_indication(&UL_INFO);
stop_meas(&gNB->ul_indication_stats); stop_meas(&gNB->ul_indication_stats);
#ifndef OAI_FHI72
notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->L1_rx_out, NULL); notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->L1_rx_out, NULL);
processingData_L1_t *syncMsg = NotifiedFifoData(res); processingData_L1_t *syncMsg = NotifiedFifoData(res);
syncMsg->gNB = gNB; syncMsg->gNB = gNB;
...@@ -228,7 +227,6 @@ static void rx_func(processingData_L1_t *info) ...@@ -228,7 +227,6 @@ static void rx_func(processingData_L1_t *info)
res->key = slot_rx; res->key = slot_rx;
LOG_D(NR_PHY, "Signaling completion for %d.%d (mod_slot %d) on L1_rx_out\n", frame_rx, slot_rx, slot_rx % RU_RX_SLOT_DEPTH); LOG_D(NR_PHY, "Signaling completion for %d.%d (mod_slot %d) on L1_rx_out\n", frame_rx, slot_rx, slot_rx % RU_RX_SLOT_DEPTH);
pushNotifiedFIFO(&gNB->L1_rx_out, res); pushNotifiedFIFO(&gNB->L1_rx_out, res);
#endif
} }
} }
......
...@@ -1084,6 +1084,48 @@ void ru_tx_func(void *param) ...@@ -1084,6 +1084,48 @@ void ru_tx_func(void *param)
}//else emulate_rf }//else emulate_rf
} }
/* @brief wait for the next RX TTI to be free
*
* Certain radios, e.g., RFsim, can run faster than real-time. This might
* create problems, e.g., if RX and TX get too far from each other. This
* function ensures that a maximum of 4 RX slots are processed at a time (and
* not more than those four are started).
*
* Through the queue L1_rx_out, we are informed about completed RX jobs.
* rx_tti_busy keeps track of individual slots that have been started; this
* function blocks until the current frame/slot is completed, signaled through
* a message.
*
* @param L1_rx_out the queue from which to read completed RX jobs
* @param rx_tti_busy array to mark RX job completion
* @param frame_rx the frame to wait for
* @param slot_rx the slot to wait for
*/
static bool wait_free_rx_tti(notifiedFIFO_t *L1_rx_out, bool rx_tti_busy[RU_RX_SLOT_DEPTH], int frame_rx, int slot_rx)
{
int idx = slot_rx % RU_RX_SLOT_DEPTH;
if (rx_tti_busy[idx]) {
bool not_done = true;
LOG_D(NR_PHY, "%d.%d Waiting to access RX slot %d\n", frame_rx, slot_rx, idx);
// block and wait for frame_rx/slot_rx free from previous slot processing.
// as we can get other slots, we loop on the queue
while (not_done) {
notifiedFIFO_elt_t *res = pullNotifiedFIFO(L1_rx_out);
if (!res)
return false;
processingData_L1_t *info = NotifiedFifoData(res);
LOG_D(NR_PHY, "%d.%d Got access to RX slot %d.%d (%d)\n", frame_rx, slot_rx, info->frame_rx, info->slot_rx, idx);
rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false;
if ((info->slot_rx % RU_RX_SLOT_DEPTH) == idx)
not_done = false;
delNotifiedFIFO_elt(res);
}
}
// set the tti to busy: the caller will process this slot now
rx_tti_busy[idx] = true;
return true;
}
void *ru_thread(void *param) void *ru_thread(void *param)
{ {
static int ru_thread_status; static int ru_thread_status;
...@@ -1097,9 +1139,7 @@ void *ru_thread(void *param) ...@@ -1097,9 +1139,7 @@ void *ru_thread(void *param)
char threadname[40]; char threadname[40];
int initial_wait = 0; int initial_wait = 0;
#ifndef OAI_FHI72
bool rx_tti_busy[RU_RX_SLOT_DEPTH] = {false}; bool rx_tti_busy[RU_RX_SLOT_DEPTH] = {false};
#endif
// set default return value // set default return value
ru_thread_status = 0; ru_thread_status = 0;
// set default return value // set default return value
...@@ -1245,39 +1285,12 @@ void *ru_thread(void *param) ...@@ -1245,39 +1285,12 @@ void *ru_thread(void *param)
if (ru->idx != 0) if (ru->idx != 0)
proc->frame_tx = (proc->frame_tx + proc->frame_offset) & 1023; proc->frame_tx = (proc->frame_tx + proc->frame_offset) & 1023;
#ifndef OAI_FHI72
// do RX front-end processing (frequency-shift, dft) if needed // do RX front-end processing (frequency-shift, dft) if needed
int slot_type = nr_slot_select(&ru->config, proc->frame_rx, proc->tti_rx); int slot_type = nr_slot_select(&ru->config, proc->frame_rx, proc->tti_rx);
if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
if (!wait_free_rx_tti(&gNB->L1_rx_out, rx_tti_busy, proc->frame_rx, proc->tti_rx))
break; // nothing to wait for: we have to stop
if (ru->feprx) { if (ru->feprx) {
if (rx_tti_busy[proc->tti_rx % RU_RX_SLOT_DEPTH]) {
bool not_done = true;
LOG_D(NR_PHY, "%d.%d Waiting to access RX slot %d\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH);
// now we block and wait our slot memory zone is freed from previous slot processing
// as we can get other slots ending, we loop on the queue
notifiedFIFO_elt_t *res = NULL;
while (not_done) {
res = pullNotifiedFIFO(&gNB->L1_rx_out);
if (!res)
break;
processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res);
LOG_D(NR_PHY,
"%d.%d Got access to RX slot %d.%d (%d)\n",
proc->frame_rx,
proc->tti_rx,
info->frame_rx,
info->slot_rx,
proc->tti_rx % RU_RX_SLOT_DEPTH);
rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false;
if ((info->slot_rx % RU_RX_SLOT_DEPTH) == (proc->tti_rx % RU_RX_SLOT_DEPTH))
not_done = false;
delNotifiedFIFO_elt(res);
}
if (!res)
break;
}
// set the tti that was generated to busy
rx_tti_busy[proc->tti_rx % RU_RX_SLOT_DEPTH] = true;
ru->feprx(ru,proc->tti_rx); ru->feprx(ru,proc->tti_rx);
LOG_D(NR_PHY, "Setting %d.%d (%d) to busy\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH); LOG_D(NR_PHY, "Setting %d.%d (%d) to busy\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH);
//LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1); //LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1);
...@@ -1315,7 +1328,6 @@ void *ru_thread(void *param) ...@@ -1315,7 +1328,6 @@ void *ru_thread(void *param)
} // end if (prach_id > 0) } // end if (prach_id > 0)
} // end if (ru->feprx) } // end if (ru->feprx)
} // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { } // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
#endif
notifiedFIFO_elt_t *resTx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL); notifiedFIFO_elt_t *resTx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL);
processingData_L1tx_t *syncMsgTx = NotifiedFifoData(resTx); processingData_L1tx_t *syncMsgTx = NotifiedFifoData(resTx);
......
This diff is collapsed.
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n" #define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n"
#define CONFIG_HLP_TIME_SYNC_P "coefficient for Proportional part of time sync PI controller\n" #define CONFIG_HLP_TIME_SYNC_P "coefficient for Proportional part of time sync PI controller\n"
#define CONFIG_HLP_TIME_SYNC_I "coefficient for Integrating part of time sync PI controller\n" #define CONFIG_HLP_TIME_SYNC_I "coefficient for Integrating part of time sync PI controller\n"
#define CONFIG_HLP_NTN_INIT_TIME_DRIFT "Initial NTN DL time drift (feeder link and service link), given in µs/s\n"
#define CONFIG_HLP_AUTONOMOUS_TA "Autonomously update TA based on DL drift (useful if main contribution to DL drift is movement, e.g. LEO satellite)\n" #define CONFIG_HLP_AUTONOMOUS_TA "Autonomously update TA based on DL drift (useful if main contribution to DL drift is movement, e.g. LEO satellite)\n"
#define CONFIG_HLP_AGC "Rx Gain control used for UE\n" #define CONFIG_HLP_AGC "Rx Gain control used for UE\n"
...@@ -62,6 +63,7 @@ ...@@ -62,6 +63,7 @@
{"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \ {"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \
{"time-sync-P", CONFIG_HLP_TIME_SYNC_P, 0, .dblptr=&(nrUE_params.time_sync_P), .defdblval=0.5, TYPE_DOUBLE, 0}, \ {"time-sync-P", CONFIG_HLP_TIME_SYNC_P, 0, .dblptr=&(nrUE_params.time_sync_P), .defdblval=0.5, TYPE_DOUBLE, 0}, \
{"time-sync-I", CONFIG_HLP_TIME_SYNC_I, 0, .dblptr=&(nrUE_params.time_sync_I), .defdblval=0.0, TYPE_DOUBLE, 0}, \ {"time-sync-I", CONFIG_HLP_TIME_SYNC_I, 0, .dblptr=&(nrUE_params.time_sync_I), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"ntn-initial-time-drift", CONFIG_HLP_NTN_INIT_TIME_DRIFT, 0, .dblptr=&(nrUE_params.ntn_init_time_drift), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"autonomous-ta", CONFIG_HLP_AUTONOMOUS_TA, PARAMFLAG_BOOL, .iptr=&(nrUE_params.autonomous_ta), .defintval=0, TYPE_INT, 0}, \ {"autonomous-ta", CONFIG_HLP_AUTONOMOUS_TA, PARAMFLAG_BOOL, .iptr=&(nrUE_params.autonomous_ta), .defintval=0, TYPE_INT, 0}, \
{"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \ {"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \
} }
...@@ -85,6 +87,7 @@ typedef struct { ...@@ -85,6 +87,7 @@ typedef struct {
int ssb_start_subcarrier; int ssb_start_subcarrier;
double time_sync_P; double time_sync_P;
double time_sync_I; double time_sync_I;
double ntn_init_time_drift;
int autonomous_ta; int autonomous_ta;
int agc; int agc;
char *usrp_args; char *usrp_args;
......
...@@ -556,9 +556,9 @@ typedef struct { ...@@ -556,9 +556,9 @@ typedef struct {
} fapi_nr_ta_command_pdu; } fapi_nr_ta_command_pdu;
typedef struct { typedef struct {
// N_common_ta_adj represents common propagation delay received in SIB19 (ms) // N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms)
double N_common_ta_adj; double N_common_ta_adj;
// N_UE_TA_adj calculated propagation delay from UE and SAT (ms) // N_UE_TA_adj calculated round-trip-time between UE and SAT (ms)
double N_UE_TA_adj; double N_UE_TA_adj;
// drift rate of common ta in µs/s // drift rate of common ta in µs/s
double ntn_ta_commondrift; double ntn_ta_commondrift;
...@@ -655,21 +655,18 @@ typedef struct ...@@ -655,21 +655,18 @@ typedef struct
typedef struct typedef struct
{ {
uint8_t slot_config;//For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot uint8_t slot_config; //For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot
} fapi_nr_max_num_of_symbol_per_slot_t; } fapi_nr_max_num_of_symbol_per_slot_t;
typedef struct typedef struct
{ {
fapi_nr_max_num_of_symbol_per_slot_t *max_num_of_symbol_per_slot_list; fapi_nr_max_num_of_symbol_per_slot_t *max_num_of_symbol_per_slot_list;
} fapi_nr_max_tdd_periodicity_t; } fapi_nr_max_tdd_periodicity_t;
typedef struct typedef struct
{ {
uint8_t tdd_period_in_slots; uint8_t tdd_period_in_slots;
fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list; fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
} fapi_nr_tdd_table_t; } fapi_nr_tdd_table_t;
typedef struct typedef struct
...@@ -709,8 +706,7 @@ typedef struct { ...@@ -709,8 +706,7 @@ typedef struct {
fapi_nr_cell_config_t cell_config; fapi_nr_cell_config_t cell_config;
fapi_nr_ssb_config_t ssb_config; fapi_nr_ssb_config_t ssb_config;
fapi_nr_ssb_table_t ssb_table; fapi_nr_ssb_table_t ssb_table;
fapi_nr_tdd_table_t tdd_table_1; fapi_nr_tdd_table_t tdd_table;
fapi_nr_tdd_table_t *tdd_table_2;
fapi_nr_prach_config_t prach_config; fapi_nr_prach_config_t prach_config;
} fapi_nr_config_request_t; } fapi_nr_config_request_t;
......
This diff is collapsed.
...@@ -60,8 +60,7 @@ void nr_layer_mapping(int nbCodes, ...@@ -60,8 +60,7 @@ void nr_layer_mapping(int nbCodes,
uint8_t n_layers, uint8_t n_layers,
int layerSz, int layerSz,
uint32_t n_symbs, uint32_t n_symbs,
c16_t tx_layers[layerSz], c16_t tx_layers[][layerSz]);
int l);
/*! \brief Perform NR layer mapping. TS 38.211 V15.4.0 subclause 7.3.1.3 /*! \brief Perform NR layer mapping. TS 38.211 V15.4.0 subclause 7.3.1.3
@param[in] ulsch_ue, double Pointer to NR_UE_ULSCH_t struct @param[in] ulsch_ue, double Pointer to NR_UE_ULSCH_t struct
...@@ -136,12 +135,10 @@ void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms, ...@@ -136,12 +135,10 @@ void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms,
c16_t nr_layer_precoder(int sz, c16_t datatx_F_precoding[][sz], const char *prec_matrix, uint8_t n_layers, int32_t re_offset); c16_t nr_layer_precoder(int sz, c16_t datatx_F_precoding[][sz], const char *prec_matrix, uint8_t n_layers, int32_t re_offset);
c16_t nr_layer_precoder_cm(int n_layers, c16_t nr_layer_precoder_cm(int n_layers,
int n_symbols,
int symSz, int symSz,
c16_t datatx_F_precoding[n_layers][n_symbols][symSz], c16_t datatx_F_precoding[n_layers][symSz],
int ap, int ap,
nfapi_nr_pm_pdu_t *pmi_pdu, nfapi_nr_pm_pdu_t *pmi_pdu,
int symbol,
int offset); int offset);
/*! \brief Precoding with SIMDe, txdataF_precoded[] = prec_matrix[] * txdataF_res_mapped[] /*! \brief Precoding with SIMDe, txdataF_precoded[] = prec_matrix[] * txdataF_res_mapped[]
...@@ -151,12 +148,10 @@ c16_t nr_layer_precoder_cm(int n_layers, ...@@ -151,12 +148,10 @@ c16_t nr_layer_precoder_cm(int n_layers,
@param[out] txdataF_precoded Precoded antenna data @param[out] txdataF_precoded Precoded antenna data
*/ */
void nr_layer_precoder_simd(const int n_layers, void nr_layer_precoder_simd(const int n_layers,
const int n_symbols,
const int symSz, const int symSz,
const c16_t txdataF_res_mapped[n_layers][n_symbols][symSz], const c16_t txdataF_res_mapped[n_layers][symSz],
const int ant, const int ant,
const nfapi_nr_pm_pdu_t *pmi_pdu, const nfapi_nr_pm_pdu_t *pmi_pdu,
const int symbol,
const int sc_offset, const int sc_offset,
const int re_cnt, const int re_cnt,
c16_t *txdataF_precoded); c16_t *txdataF_precoded);
......
...@@ -99,7 +99,7 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -99,7 +99,7 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
if (dci_pdu->RNTI != 0xFFFF) if (dci_pdu->RNTI != 0xFFFF)
LOG_D(NR_PHY_DCI, LOG_D(NR_PHY_DCI,
"DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d, " "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d, "
"reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d\n", "reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d AggregationLevel %d\n",
rb_offset, rb_offset,
n_rb, n_rb,
dmrs_length, dmrs_length,
...@@ -108,7 +108,8 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -108,7 +108,8 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
pdcch_pdu_rel15->CceRegMappingType, pdcch_pdu_rel15->CceRegMappingType,
dci_pdu->ScramblingId, dci_pdu->ScramblingId,
dci_pdu->ScramblingRNTI, dci_pdu->ScramblingRNTI,
dci_pdu->PayloadSizeBits); dci_pdu->PayloadSizeBits,
dci_pdu->AggregationLevel);
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
/// DMRS QPSK modulation /// DMRS QPSK modulation
...@@ -162,7 +163,7 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -162,7 +163,7 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] ); scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] );
#endif #endif
/// QPSK modulation /// QPSK modulation
c16_t mod_dci[NR_MAX_DCI_SIZE >> 2] __attribute__((aligned(16))); c16_t mod_dci[NR_MAX_DCI_SIZE / 2] __attribute__((aligned(16)));
nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, (int16_t *)mod_dci); // Qm = 2 as DMRS is QPSK modulated nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, (int16_t *)mod_dci); // Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_DCI #ifdef DEBUG_DCI
...@@ -248,9 +249,11 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_off ...@@ -248,9 +249,11 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_off
{ {
PHY_VARS_gNB *gNB = msgTx->gNB; PHY_VARS_gNB *gNB = msgTx->gNB;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
start_meas(&gNB->dci_generation_stats);
for (int i = 0; i < msgTx->num_ul_pdcch; i++) for (int i = 0; i < msgTx->num_ul_pdcch; i++)
nr_generate_dci(msgTx->gNB, &msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, frame_parms, slot); nr_generate_dci(msgTx->gNB, &msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
for (int i = 0; i < msgTx->num_dl_pdcch; i++) for (int i = 0; i < msgTx->num_dl_pdcch; i++)
nr_generate_dci(msgTx->gNB, &msgTx->pdcch_pdu[i].pdcch_pdu_rel15, txdataF_offset, frame_parms, slot); nr_generate_dci(msgTx->gNB, &msgTx->pdcch_pdu[i].pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
stop_meas(&gNB->dci_generation_stats);
} }
This diff is collapsed.
...@@ -520,6 +520,8 @@ typedef struct PHY_VARS_gNB_s { ...@@ -520,6 +520,8 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t dlsch_interleaving_stats; time_stats_t dlsch_interleaving_stats;
time_stats_t dlsch_segmentation_stats; time_stats_t dlsch_segmentation_stats;
time_stats_t dci_generation_stats;
time_stats_t phase_comp_stats;
time_stats_t rx_pusch_stats; time_stats_t rx_pusch_stats;
time_stats_t rx_pusch_init_stats; time_stats_t rx_pusch_init_stats;
time_stats_t rx_pusch_symbol_processing_stats; time_stats_t rx_pusch_symbol_processing_stats;
......
...@@ -395,7 +395,7 @@ void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) { ...@@ -395,7 +395,7 @@ void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) {
void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu) void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu)
{ {
frame_structure_t fs = {.is_tdd = true}; frame_structure_t fs = {.frame_type = TDD};
fs.numb_slots_frame = (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; fs.numb_slots_frame = (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
fs.numb_period_frame = get_nb_periods_per_frame(gNB->gNB_config.tdd_table.tdd_period.value); fs.numb_period_frame = get_nb_periods_per_frame(gNB->gNB_config.tdd_table.tdd_period.value);
fs.numb_slots_period = fs.numb_slots_frame / fs.numb_period_frame; fs.numb_slots_period = fs.numb_slots_frame / fs.numb_period_frame;
......
...@@ -290,6 +290,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, ...@@ -290,6 +290,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
//apply the OFDM symbol rotation here //apply the OFDM symbol rotation here
if (gNB->phase_comp) { if (gNB->phase_comp) {
start_meas(&gNB->phase_comp_stats);
for(int i = 0; i < gNB->common_vars.num_beams_period; ++i) { for(int i = 0; i < gNB->common_vars.num_beams_period; ++i) {
for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) {
apply_nr_rotation_TX(fp, apply_nr_rotation_TX(fp,
...@@ -304,6 +305,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, ...@@ -304,6 +305,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
T_INT(aa), T_BUFFER(&gNB->common_vars.txdataF[aa][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t))); T_INT(aa), T_BUFFER(&gNB->common_vars.txdataF[aa][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t)));
} }
} }
stop_meas(&gNB->phase_comp_stats);
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 0);
......
...@@ -44,14 +44,8 @@ int nr_ue_slot_select(const fapi_nr_config_request_t *cfg, int nr_slot) ...@@ -44,14 +44,8 @@ int nr_ue_slot_select(const fapi_nr_config_request_t *cfg, int nr_slot)
if (cfg->cell_config.frame_duplex_type == FDD) if (cfg->cell_config.frame_duplex_type == FDD)
return NR_UPLINK_SLOT | NR_DOWNLINK_SLOT; return NR_UPLINK_SLOT | NR_DOWNLINK_SLOT;
int period = cfg->tdd_table_1.tdd_period_in_slots + const fapi_nr_tdd_table_t *tdd_table = &cfg->tdd_table;
(cfg->tdd_table_2 ? cfg->tdd_table_2->tdd_period_in_slots : 0); int rel_slot = nr_slot % tdd_table->tdd_period_in_slots;
int rel_slot = nr_slot % period;
const fapi_nr_tdd_table_t *tdd_table = &cfg->tdd_table_1;
if (cfg->tdd_table_2 && rel_slot >= tdd_table->tdd_period_in_slots) {
rel_slot -= tdd_table->tdd_period_in_slots;
tdd_table = cfg->tdd_table_2;
}
if (tdd_table->max_tdd_periodicity_list == NULL) // this happens before receiving TDD configuration if (tdd_table->max_tdd_periodicity_list == NULL) // this happens before receiving TDD configuration
return NR_DOWNLINK_SLOT; return NR_DOWNLINK_SLOT;
......
...@@ -647,7 +647,11 @@ printf("%d\n", slot); ...@@ -647,7 +647,11 @@ printf("%d\n", slot);
frame_structure_t frame_structure = {0}; frame_structure_t frame_structure = {0};
frame_type_t frame_type = TDD; frame_type_t frame_type = TDD;
config_frame_structure(mu, scc, get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon), frame_type, &frame_structure); config_frame_structure(mu,
scc->tdd_UL_DL_ConfigurationCommon,
get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon),
frame_type,
&frame_structure);
AssertFatal(is_dl_slot(slot, &frame_structure), "The slot selected is not DL. Can't run DLSIM\n"); AssertFatal(is_dl_slot(slot, &frame_structure), "The slot selected is not DL. Can't run DLSIM\n");
// TODO do a UECAP for phy-sim // TODO do a UECAP for phy-sim
...@@ -671,7 +675,8 @@ printf("%d\n", slot); ...@@ -671,7 +675,8 @@ printf("%d\n", slot);
.timer_config.n310 = 10, .timer_config.n310 = 10,
.timer_config.t311 = 3000, .timer_config.t311 = 3000,
.timer_config.n311 = 1, .timer_config.n311 = 1,
.timer_config.t319 = 400}; .timer_config.t319 = 400,
.num_agg_level_candidates = {0, 0, 1, 1, 0}};
RC.nb_nr_macrlc_inst = 1; RC.nb_nr_macrlc_inst = 1;
RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int));
...@@ -858,7 +863,7 @@ printf("%d\n", slot); ...@@ -858,7 +863,7 @@ printf("%d\n", slot);
nr_l2_init_ue(1); nr_l2_init_ue(1);
UE_mac = get_mac_inst(0); UE_mac = get_mac_inst(0);
ue_init_config_request(UE_mac, mu); ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
UE->if_inst = nr_ue_if_module_init(0); UE->if_inst = nr_ue_if_module_init(0);
UE->if_inst->scheduled_response = nr_ue_scheduled_response; UE->if_inst->scheduled_response = nr_ue_scheduled_response;
...@@ -960,10 +965,12 @@ printf("%d\n", slot); ...@@ -960,10 +965,12 @@ printf("%d\n", slot);
reset_meas(&gNB->dlsch_segmentation_stats); reset_meas(&gNB->dlsch_segmentation_stats);
reset_meas(&gNB->dlsch_modulation_stats); reset_meas(&gNB->dlsch_modulation_stats);
reset_meas(&gNB->dlsch_encoding_stats); reset_meas(&gNB->dlsch_encoding_stats);
reset_meas(&gNB->dci_generation_stats);
reset_meas(&gNB->tinput); reset_meas(&gNB->tinput);
reset_meas(&gNB->tprep); reset_meas(&gNB->tprep);
reset_meas(&gNB->tparity); reset_meas(&gNB->tparity);
reset_meas(&gNB->toutput); reset_meas(&gNB->toutput);
reset_meas(&gNB->phase_comp_stats);
uint32_t errors_scrambling[16] = {0}; uint32_t errors_scrambling[16] = {0};
int n_errors[16] = {0}; int n_errors[16] = {0};
...@@ -1259,6 +1266,7 @@ printf("%d\n", slot); ...@@ -1259,6 +1266,7 @@ printf("%d\n", slot);
UE->dl_harq_processes[0][slot].C, UE->dl_harq_processes[0][slot].C,
msgDataTx->dlsch[0][0].harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0] << 3); msgDataTx->dlsch[0][0].harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0] << 3);
printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx"); printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx");
printStatIndent2(&gNB->dci_generation_stats, "DCI encoding time");
printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time"); printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");
printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time"); printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time");
printStatIndent3(&gNB->tinput,"DLSCH LDPC input processing time"); printStatIndent3(&gNB->tinput,"DLSCH LDPC input processing time");
...@@ -1269,8 +1277,9 @@ printf("%d\n", slot); ...@@ -1269,8 +1277,9 @@ printf("%d\n", slot);
printStatIndent3(&gNB->dlsch_interleaving_stats, "DLSCH Interleaving time"); printStatIndent3(&gNB->dlsch_interleaving_stats, "DLSCH Interleaving time");
printStatIndent2(&gNB->dlsch_modulation_stats,"DLSCH modulation time"); printStatIndent2(&gNB->dlsch_modulation_stats,"DLSCH modulation time");
printStatIndent2(&gNB->dlsch_scrambling_stats, "DLSCH scrambling time"); printStatIndent2(&gNB->dlsch_scrambling_stats, "DLSCH scrambling time");
printStatIndent2(&gNB->dlsch_resource_mapping_stats, "DLSCH Resource Mapping time"); printStatIndent2(&gNB->dlsch_precoding_stats,"DLSCH Mapping/Precoding time");
printStatIndent2(&gNB->dlsch_precoding_stats,"DLSCH Layer Precoding time"); if (gNB->phase_comp)
printStatIndent2(&gNB->phase_comp_stats, "Phase Compensation");
printf("\nUE function statistics (per %d us slot)\n", 1000 >> *scc->ssbSubcarrierSpacing); printf("\nUE function statistics (per %d us slot)\n", 1000 >> *scc->ssbSubcarrierSpacing);
for (int i = RX_PDSCH_STATS; i <= DLSCH_PROCEDURES_STATS; i++) { for (int i = RX_PDSCH_STATS; i <= DLSCH_PROCEDURES_STATS; i++) {
......
...@@ -628,7 +628,11 @@ int main(int argc, char *argv[]) ...@@ -628,7 +628,11 @@ int main(int argc, char *argv[])
frame_structure_t frame_structure = {0}; frame_structure_t frame_structure = {0};
frame_type_t frame_type = TDD; frame_type_t frame_type = TDD;
config_frame_structure(mu, scc, get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon), frame_type, &frame_structure); config_frame_structure(mu,
scc->tdd_UL_DL_ConfigurationCommon,
get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon),
frame_type,
&frame_structure);
AssertFatal(is_ul_slot(slot, &frame_structure), "The slot selected is not UL. Can't run ULSIM\n"); AssertFatal(is_ul_slot(slot, &frame_structure), "The slot selected is not UL. Can't run ULSIM\n");
// TODO do a UECAP for phy-sim // TODO do a UECAP for phy-sim
...@@ -737,7 +741,7 @@ int main(int argc, char *argv[]) ...@@ -737,7 +741,7 @@ int main(int argc, char *argv[])
nr_l2_init_ue(1); nr_l2_init_ue(1);
NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0); NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0);
ue_init_config_request(UE_mac, mu); ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
UE->if_inst = nr_ue_if_module_init(0); UE->if_inst = nr_ue_if_module_init(0);
UE->if_inst->scheduled_response = nr_ue_scheduled_response; UE->if_inst->scheduled_response = nr_ue_scheduled_response;
......
...@@ -477,9 +477,11 @@ typedef struct { ...@@ -477,9 +477,11 @@ typedef struct {
} nr_mac_rrc_config_mib_t; } nr_mac_rrc_config_mib_t;
typedef struct { typedef struct {
NR_SIB1_t *sib1; NR_SIB1_t *sib1;
bool can_start_ra;
} nr_mac_rrc_config_sib1_t; } nr_mac_rrc_config_sib1_t;
typedef struct { typedef struct {
NR_SIB19_r17_t *sib19; NR_SIB19_r17_t *sib19;
bool can_start_ra;
} nr_mac_rrc_config_other_sib_t; } nr_mac_rrc_config_other_sib_t;
#endif /* RRC_MESSAGES_TYPES_H_ */ #endif /* RRC_MESSAGES_TYPES_H_ */
...@@ -169,7 +169,7 @@ static void fill_rc_report(ran_func_def_report_t* report) ...@@ -169,7 +169,7 @@ static void fill_rc_report(ran_func_def_report_t* report)
// Mandatory // Mandatory
// 9.3.8 // 9.3.8
// [1- 4294967295] // [1- 4294967295]
report_style->ran_param[0].id = RRC_STATE_CHANGED_TO_E2SM_RC_RAN_PARAM_ID; report_style->ran_param[0].id = E2SM_RC_RS4_RRC_STATE_CHANGED_TO;
// RAN Parameter Name // RAN Parameter Name
// Mandatory // Mandatory
...@@ -476,14 +476,11 @@ void read_rc_setup_sm(void* data) ...@@ -476,14 +476,11 @@ void read_rc_setup_sm(void* data)
DevAssert(ret == 0); DevAssert(ret == 0);
} }
RB_PROTOTYPE(ric_id_2_param_id_trees, ric_req_id_s, entries, cmp_ric_req_id);
static seq_ran_param_t fill_rrc_state_change_seq_ran(const rc_sm_rrc_state_e rrc_state) static seq_ran_param_t fill_rrc_state_change_seq_ran(const rc_sm_rrc_state_e rrc_state)
{ {
seq_ran_param_t seq_ran_param = {0}; seq_ran_param_t seq_ran_param = {0};
seq_ran_param.ran_param_id = RRC_STATE_CHANGED_TO_E2SM_RC_RAN_PARAM_ID; seq_ran_param.ran_param_id = E2SM_RC_RS4_RRC_STATE_CHANGED_TO;
seq_ran_param.ran_param_val.type = ELEMENT_KEY_FLAG_FALSE_RAN_PARAMETER_VAL_TYPE; seq_ran_param.ran_param_val.type = ELEMENT_KEY_FLAG_FALSE_RAN_PARAMETER_VAL_TYPE;
seq_ran_param.ran_param_val.flag_false = calloc(1, sizeof(ran_parameter_value_t)); seq_ran_param.ran_param_val.flag_false = calloc(1, sizeof(ran_parameter_value_t));
assert(seq_ran_param.ran_param_val.flag_false != NULL && "Memory exhausted"); assert(seq_ran_param.ran_param_val.flag_false != NULL && "Memory exhausted");
...@@ -528,21 +525,38 @@ static rc_ind_data_t* fill_ue_rrc_state_change(const gNB_RRC_UE_t *rrc_ue_contex ...@@ -528,21 +525,38 @@ static rc_ind_data_t* fill_ue_rrc_state_change(const gNB_RRC_UE_t *rrc_ue_contex
return rc_ind; return rc_ind;
} }
static void send_aper_ric_ind(const uint32_t ric_req_id, rc_ind_data_t* rc_ind_data)
{
async_event_agent_api(ric_req_id, rc_ind_data);
printf("[E2 AGENT] Event for RIC request ID %d generated\n", ric_req_id);
}
static void check_rrc_state(const gNB_RRC_UE_t *rrc_ue_context, const rc_sm_rrc_state_e rrc_state, const uint32_t ric_req_id, const e2sm_rc_ev_trg_frmt_4_t *frmt_4)
{
for (size_t i = 0; i < frmt_4->sz_ue_info_chng; i++) {
const rrc_state_lst_t *rrc_elem = &frmt_4->ue_info_chng[i].rrc_state;
for (size_t j = 0; j < rrc_elem->sz_rrc_state; j++) {
const rrc_state_e2sm_rc_e ev_tr_rrc_state = rrc_elem->state_chng_to[j].state_chngd_to;
if (ev_tr_rrc_state == (rrc_state_e2sm_rc_e)rrc_state || ev_tr_rrc_state == ANY_RRC_STATE_E2SM_RC) {
rc_ind_data_t* rc_ind_data = fill_ue_rrc_state_change(rrc_ue_context, rrc_state);
send_aper_ric_ind(ric_req_id, rc_ind_data);
}
}
}
}
void signal_rrc_state_changed_to(const gNB_RRC_UE_t *rrc_ue_context, const rc_sm_rrc_state_e rrc_state) void signal_rrc_state_changed_to(const gNB_RRC_UE_t *rrc_ue_context, const rc_sm_rrc_state_e rrc_state)
{ {
pthread_mutex_lock(&rc_mutex); pthread_mutex_lock(&rc_mutex);
if (rc_subs_data.rb[RRC_STATE_CHANGED_TO_E2SM_RC_RAN_PARAM_ID].rbh_root == NULL) { if (rc_subs_data.rs4_param202.data == NULL) {
pthread_mutex_unlock(&rc_mutex); pthread_mutex_unlock(&rc_mutex);
return; return;
} }
struct ric_req_id_s *node; const size_t num_subs = seq_arr_size(&rc_subs_data.rs4_param202);
RB_FOREACH(node, ric_id_2_param_id_trees, &rc_subs_data.rb[RRC_STATE_CHANGED_TO_E2SM_RC_RAN_PARAM_ID]) { for (size_t sub_idx = 0; sub_idx < num_subs; sub_idx++) {
rc_ind_data_t* rc_ind_data = fill_ue_rrc_state_change(rrc_ue_context, rrc_state); const ran_param_data_t data = *(const ran_param_data_t *)seq_arr_at(&rc_subs_data.rs4_param202, sub_idx);
check_rrc_state(rrc_ue_context, rrc_state, data.ric_req_id, &data.ev_tr.frmt_4);
// Needs review: memory ownership of the type rc_ind_data_t is transferred to the E2 Agent. Bad
async_event_agent_api(node->ric_req_id, rc_ind_data);
printf( "Event for RIC Req ID %u generated\n", node->ric_req_id);
} }
pthread_mutex_unlock(&rc_mutex); pthread_mutex_unlock(&rc_mutex);
...@@ -553,38 +567,65 @@ static void free_aperiodic_subscription(uint32_t ric_req_id) ...@@ -553,38 +567,65 @@ static void free_aperiodic_subscription(uint32_t ric_req_id)
remove_rc_subs_data(&rc_subs_data, ric_req_id); remove_rc_subs_data(&rc_subs_data, ric_req_id);
} }
static seq_arr_t *get_sa(const e2sm_rc_event_trigger_t *ev_tr, const uint32_t ran_param_id)
{
seq_arr_t *sa = NULL;
switch (ev_tr->format) {
case FORMAT_4_E2SM_RC_EV_TRIGGER_FORMAT:
if (ran_param_id == E2SM_RC_RS4_RRC_STATE_CHANGED_TO) {
sa = &rc_subs_data.rs4_param202;
}
break;
default:
printf("[E2 AGENT] RC REPORT Style %d not yet implemented.\n", ev_tr->format + 1);
break;
}
return sa;
}
static void get_list_for_report_style(const uint32_t ric_req_id, const e2sm_rc_event_trigger_t *ev_tr, const size_t sz, const param_report_def_t *param_def)
{
for (size_t i = 0; i < sz; i++) {
seq_arr_t *sa = get_sa(ev_tr, param_def[i].ran_param_id);
if (!sa) {
printf("[E2 AGENT] Requested RAN Parameter ID %d not yet implemented", param_def[i].ran_param_id);
} else {
struct ran_param_data data = { .ric_req_id = ric_req_id, .ev_tr = cp_e2sm_rc_event_trigger(ev_tr) };
insert_rc_subs_data(sa, &data);
}
}
}
sm_ag_if_ans_t write_subs_rc_sm(void const* src) sm_ag_if_ans_t write_subs_rc_sm(void const* src)
{ {
assert(src != NULL); // && src->type == RAN_CTRL_SUBS_V1_03); assert(src != NULL); // && src->type == RAN_CTRL_SUBS_V1_03);
wr_rc_sub_data_t* wr_rc = (wr_rc_sub_data_t*)src; wr_rc_sub_data_t* wr_rc = (wr_rc_sub_data_t*)src;
assert(wr_rc->rc.ad != NULL && "Cannot be NULL"); assert(wr_rc->rc.ad != NULL && "Cannot be NULL");
sm_ag_if_ans_t ans = {0};
const uint32_t ric_req_id = wr_rc->ric_req_id;
const uint32_t report_style = wr_rc->rc.ad->ric_style_type;
// 9.2.1.2 RIC ACTION DEFINITION IE // 9.2.1.2 RIC ACTION DEFINITION IE
switch (wr_rc->rc.ad->format) { switch (wr_rc->rc.ad->format) {
case FORMAT_1_E2SM_RC_ACT_DEF: { case FORMAT_1_E2SM_RC_ACT_DEF: { // for all REPORT styles
// Parameters to be Reported List // Parameters to be Reported List
// [1-65535] // [1-65535]
const uint32_t ric_req_id = wr_rc->ric_req_id; if (wr_rc->rc.et.format + 1 != report_style) { // wr_rc->rc.et.format is an enum -> initialization starts from 0
arr_ran_param_id_t* arr_ran_param_id = calloc(1, sizeof(arr_ran_param_id_t)); AssertError(false, return ans, "[E2 AGENT] Event Trigger Definition Format %d doesn't correspond to REPORT style %d.\n", wr_rc->rc.et.format + 1, report_style);
assert(arr_ran_param_id != NULL && "Memory exhausted");
arr_ran_param_id->len = wr_rc->rc.ad->frmt_1.sz_param_report_def;
arr_ran_param_id->ran_param_id = calloc(arr_ran_param_id->len, sizeof(ran_param_id_e));
const size_t sz = arr_ran_param_id->len;
for(size_t i = 0; i < sz; i++) {
arr_ran_param_id->ran_param_id[i] = wr_rc->rc.ad->frmt_1.param_report_def[i].ran_param_id;
} }
insert_rc_subs_data(&rc_subs_data, ric_req_id, arr_ran_param_id); get_list_for_report_style(ric_req_id, &wr_rc->rc.et, wr_rc->rc.ad->frmt_1.sz_param_report_def, wr_rc->rc.ad->frmt_1.param_report_def);
break; break;
} }
default: default:
AssertFatal(wr_rc->rc.ad->format == FORMAT_1_E2SM_RC_ACT_DEF, "Action Definition Format %d not yet implemented", wr_rc->rc.ad->format); AssertError(wr_rc->rc.ad->format == FORMAT_1_E2SM_RC_ACT_DEF, return ans, "[E2 AGENT] Action Definition Format %d not yet implemented", wr_rc->rc.ad->format + 1);
} }
sm_ag_if_ans_t ans = {.type = SUBS_OUTCOME_SM_AG_IF_ANS_V0}; ans.type = SUBS_OUTCOME_SM_AG_IF_ANS_V0;
ans.subs_out.type = APERIODIC_SUBSCRIPTION_FLRC; ans.subs_out.type = APERIODIC_SUBSCRIPTION_FLRC;
ans.subs_out.aper.free_aper_subs = free_aperiodic_subscription; ans.subs_out.aper.free_aper_subs = free_aperiodic_subscription;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "ran_func_rc_subs.h" #include "ran_func_rc_subs.h"
#include "common/utils/assertions.h" #include "common/utils/assertions.h"
#include "common/utils/alg/find.h"
#include <assert.h> #include <assert.h>
#include <pthread.h> #include <pthread.h>
...@@ -29,86 +30,36 @@ ...@@ -29,86 +30,36 @@
static pthread_mutex_t rc_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t rc_mutex = PTHREAD_MUTEX_INITIALIZER;
int cmp_ric_req_id(struct ric_req_id_s *c1, struct ric_req_id_s *c2) static bool eq_int(const void* value, const void* it)
{ {
if (c1->ric_req_id < c2->ric_req_id) const uint32_t ric_req_id = *(uint32_t *)value;
return -1; const ran_param_data_t *dit = (const ran_param_data_t *)it;
return ric_req_id == dit->ric_req_id;
if (c1->ric_req_id > c2->ric_req_id)
return 1;
return 0;
} }
RB_GENERATE(ric_id_2_param_id_trees, ric_req_id_s, entries, cmp_ric_req_id); void init_rc_subs_data(rc_subs_data_t *rc_subs_data)
void init_rc_subs_data(rc_subs_data_t* rc_subs_data)
{ {
pthread_mutex_lock(&rc_mutex); pthread_mutex_lock(&rc_mutex);
// Initialize sequence array
// Initialize hash table seq_arr_init(&rc_subs_data->rs4_param202, sizeof(ran_param_data_t));
DevAssert(rc_subs_data->htable == NULL);
// Initialize RB trees
// 1 RB tree = 1 ran_param_id => many ric_req_id(s)
for (size_t i = 0; i < END_E2SM_RC_RAN_PARAM_ID; i++) {
RB_INIT(&rc_subs_data->rb[i]);
}
rc_subs_data->htable = hashtable_create(MAX_NUM_RIC_REQ_ID, NULL, free);
assert(rc_subs_data->htable != NULL && "Memory exhausted");
pthread_mutex_unlock(&rc_mutex); pthread_mutex_unlock(&rc_mutex);
} }
void insert_rc_subs_data(rc_subs_data_t* rc_subs_data, uint32_t ric_req_id, arr_ran_param_id_t* arr_ran_param_id) void insert_rc_subs_data(seq_arr_t *seq_arr, ran_param_data_t *data)
{ {
pthread_mutex_lock(&rc_mutex); pthread_mutex_lock(&rc_mutex);
// Insert (RIC request ID + Event Trigger Definition) in specific RAN Parameter ID sequence
// Insert in hash table seq_arr_push_back(seq_arr, data, sizeof(*data));
DevAssert(rc_subs_data->htable != NULL);
uint64_t key = ric_req_id;
// Check if the subscription already exists
AssertFatal(hashtable_is_key_exists(rc_subs_data->htable, key) == HASH_TABLE_KEY_NOT_EXISTS, "RIC req ID %d already subscribed", ric_req_id);
arr_ran_param_id_t* data = malloc(sizeof(*data));
assert(data != NULL);
*data = *arr_ran_param_id;
hashtable_rc_t ret = hashtable_insert(rc_subs_data->htable, key, data);
assert(ret == HASH_TABLE_OK && "Hash table not ok");
// Insert in RB trees
// 1 RB tree = 1 ran_param_id => many ric_req_id(s)
const size_t sz = arr_ran_param_id->len;
rb_ric_req_id_t *node = calloc(1, sizeof(*node));
assert(node != NULL);
node->ric_req_id = ric_req_id;
for (size_t i = 0; i < sz; i++) {
RB_INSERT(ric_id_2_param_id_trees, &rc_subs_data->rb[arr_ran_param_id->ran_param_id[i]], node);
}
pthread_mutex_unlock(&rc_mutex); pthread_mutex_unlock(&rc_mutex);
} }
void remove_rc_subs_data(rc_subs_data_t* rc_subs_data, uint32_t ric_req_id) void remove_rc_subs_data(rc_subs_data_t *rc_subs_data, uint32_t ric_req_id)
{ {
pthread_mutex_lock(&rc_mutex); pthread_mutex_lock(&rc_mutex);
DevAssert(rc_subs_data->htable != NULL); /* find the sequence element that matches RIC request ID */
elm_arr_t elm = find_if(&rc_subs_data->rs4_param202, (void *)&ric_req_id, eq_int);
uint64_t key = ric_req_id; ran_param_data_t *data = elm.it;
// Get the array of ran_param_id(s) free_e2sm_rc_event_trigger(&data->ev_tr);
void *data = NULL; seq_arr_erase(&rc_subs_data->rs4_param202, elm.it);
hashtable_rc_t ret = hashtable_get(rc_subs_data->htable, key, &data);
AssertFatal(ret == HASH_TABLE_OK && data != NULL, "element for ue_id %d not found\n", ric_req_id);
arr_ran_param_id_t arr_ran_param_id = *(arr_ran_param_id_t *)data;
// Remove ric_req_id with its ran_param_id(s) from hash table
ret = hashtable_remove(rc_subs_data->htable, key);
// Remove ric_req_id from each ran_param_id tree where subscribed
rb_ric_req_id_t *node = calloc(1, sizeof(*node));
assert(node != NULL);
node->ric_req_id = ric_req_id;
for (size_t i = 0; i < arr_ran_param_id.len; i++) {
RB_REMOVE(ric_id_2_param_id_trees, &rc_subs_data->rb[arr_ran_param_id.ran_param_id[i]], node);
}
pthread_mutex_unlock(&rc_mutex); pthread_mutex_unlock(&rc_mutex);
} }
...@@ -22,35 +22,74 @@ ...@@ -22,35 +22,74 @@
#ifndef RAN_FUNC_SM_RAN_CTRL_SUBSCRIPTION_AGENT_H #ifndef RAN_FUNC_SM_RAN_CTRL_SUBSCRIPTION_AGENT_H
#define RAN_FUNC_SM_RAN_CTRL_SUBSCRIPTION_AGENT_H #define RAN_FUNC_SM_RAN_CTRL_SUBSCRIPTION_AGENT_H
#include "common/utils/hashtable/hashtable.h" #include "openair2/E2AP/flexric/src/sm/rc_sm/ie/rc_data_ie.h"
#include "common/utils/collection/tree.h" #include "common/utils/ds/seq_arr.h"
typedef enum { typedef enum { // 8.2.1 RAN Parameters for Report Service Style 1
RRC_STATE_CHANGED_TO_E2SM_RC_RAN_PARAM_ID = 202, // 8.2.4 RAN Parameters for Report Service Style 4 E2SM_RC_RS1_UE_EVENT_ID = 1,
E2SM_RC_RS1_NI_MESSAGE = 2,
E2SM_RC_RS1_RRC_MESSAGE = 3,
E2SM_RC_RS1_UE_ID = 4,
E2SM_RC_RS1_OLD_AMF_UE_NGAP_ID = 5,
E2SM_RC_RS1_CELL_GLOBAL_ID = 6,
END_E2SM_RC_RAN_PARAM_ID END_E2SM_RC_RS1_RAN_PARAM_ID
} ran_param_id_e; } report_style_1_ran_param_id_e;
typedef struct{ typedef enum { // 8.2.2 RAN Parameters for Report Service Style 2
size_t len; E2SM_RC_RS2_CURRENT_UE_ID = 1,
ran_param_id_e* ran_param_id; E2SM_RC_RS2_OLD_UE_ID = 2,
} arr_ran_param_id_t; E2SM_RC_RS2_CURRENT_RRC_STATE = 3,
E2SM_RC_RS2_OLD_RRC_STATE = 4,
E2SM_RC_RS2_UE_CONTEXT_INFORMATION_CONTAINER = 5,
E2SM_RC_RS2_CELL_GLOBAL_ID = 6,
E2SM_RC_RS2_UE_INFORMATION = 7,
typedef struct ric_req_id_s { END_E2SM_RC_RS2_RAN_PARAM_ID
RB_ENTRY(ric_req_id_s) entries; } report_style_2_ran_param_id_e;
typedef enum { // 8.2.3 RAN Parameters for Report Service Style 3
E2SM_RC_RS3_CELL_CONTEXT_INFORMATION = 1,
E2SM_RC_RS3_CELL_DELETED = 2,
E2SM_RC_RS3_NEIGHBOUR_RELATION_TABLE = 3,
END_E2SM_RC_RS3_RAN_PARAM_ID
} report_style_3_ran_param_id_e;
typedef enum { // 8.2.4 RAN Parameters for Report Service Style 4
E2SM_RC_RS4_UL_MAC_CE = 100,
E2SM_RC_RS4_DL_MAC_CE = 101,
E2SM_RC_RS4_DL_BUFFER_OCCUPANCY = 102,
E2SM_RC_RS4_CURRENT_RRC_STATE = 201,
E2SM_RC_RS4_RRC_STATE_CHANGED_TO = 202,
E2SM_RC_RS4_RRC_MESSAGE = 203,
E2SM_RC_RS4_OLD_UE_ID = 300,
E2SM_RC_RS4_CURRENT_UE_ID = 301,
E2SM_RC_RS4_NI_MESSAGE = 302,
E2SM_RC_RS4_CELL_GLOBAL_ID = 400,
END_E2SM_RC_RS4_RAN_PARAM_ID
} report_style_4_ran_param_id_e;
typedef enum { // 8.2.5 RAN Parameters for Report Service Style 5
E2SM_RC_RS5_UE_CONTEXT_INFORMATION = 1,
E2SM_RC_RS5_CELL_CONTEXT_INFORMATION = 2,
E2SM_RC_RS5_NEIGHBOUR_RELATION_TABLE = 3,
END_E2SM_RC_RS5_RAN_PARAM_ID
} report_style_5_ran_param_id_e;
typedef struct ran_param_data {
uint32_t ric_req_id; uint32_t ric_req_id;
} rb_ric_req_id_t; e2sm_rc_event_trigger_t ev_tr;
} ran_param_data_t;
typedef struct { typedef struct {
RB_HEAD(ric_id_2_param_id_trees, ric_req_id_s) rb[END_E2SM_RC_RAN_PARAM_ID]; // 1 RB tree = (1 RAN Parameter ID) : (n RIC Request ID) => m RB tree = (m RAN Parameter ID) : (n RIC Request ID) seq_arr_t rs4_param202; // E2SM_RC_RS4_RRC_STATE_CHANGED_TO
hash_table_t* htable; // 1 Hash table = (n RIC Request ID) : (m RAN Parameter ID)
} rc_subs_data_t; } rc_subs_data_t;
void init_rc_subs_data(rc_subs_data_t *rc_subs_data);
int cmp_ric_req_id(struct ric_req_id_s *c1, struct ric_req_id_s *c2); void insert_rc_subs_data(seq_arr_t *seq_arr, ran_param_data_t *data);
void remove_rc_subs_data(rc_subs_data_t *rc_subs_data, uint32_t ric_req_id);
void init_rc_subs_data(rc_subs_data_t* rc_subs_data);
void insert_rc_subs_data(rc_subs_data_t* rc_subs_data, uint32_t ric_req_id, arr_ran_param_id_t* arr_ran_param_id);
void remove_rc_subs_data(rc_subs_data_t* rc_subs_data, uint32_t ric_req_id);
#endif #endif
...@@ -132,6 +132,7 @@ ...@@ -132,6 +132,7 @@
#define GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VY "velocityVY-r17" #define GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VY "velocityVY-r17"
#define GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VZ "velocityVZ-r17" #define GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VZ "velocityVZ-r17"
#define GNB_CONFIG_STRING_TA_COMMON "ta-Common-r17" #define GNB_CONFIG_STRING_TA_COMMON "ta-Common-r17"
#define GNB_CONFIG_STRING_TA_COMMONDRIFT "ta-CommonDrift-r17"
#define CARRIERBANDWIDTH_OKVALUES {11,18,24,25,31,32,38,51,52,65,66,78,79,93,106,107,121,132,133,135,160,162,189,216,217,245,264,270,273} #define CARRIERBANDWIDTH_OKVALUES {11,18,24,25,31,32,38,51,52,65,66,78,79,93,106,107,121,132,133,135,160,162,189,216,217,245,264,270,273}
...@@ -257,6 +258,7 @@ ...@@ -257,6 +258,7 @@
{GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VY,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->velocityVY_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \ {GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VY,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->velocityVY_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VZ,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->velocityVZ_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \ {GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VZ,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->velocityVZ_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_TA_COMMON,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ta_Info_r17->ta_Common_r17,.defint64val=-1,TYPE_INT64,0}, \ {GNB_CONFIG_STRING_TA_COMMON,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ta_Info_r17->ta_Common_r17,.defint64val=-1,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_TA_COMMONDRIFT,NULL,0,.i64ptr=scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17,.defint64val=0,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,.defintval=-1,TYPE_INT64,0}} {GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,.defintval=-1,TYPE_INT64,0}}
#define SCC_PATTERN2_STRING_CONFIG "pattern2" #define SCC_PATTERN2_STRING_CONFIG "pattern2"
......
...@@ -185,6 +185,7 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) ...@@ -185,6 +185,7 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc)
scc->ext2->ntn_Config_r17->ephemerisInfo_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17)); scc->ext2->ntn_Config_r17->ephemerisInfo_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17));
scc->ext2->ntn_Config_r17->ta_Info_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17)); scc->ext2->ntn_Config_r17->ta_Info_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17));
scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17));
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->present = NR_EphemerisInfo_r17_PR_positionVelocity_r17; scc->ext2->ntn_Config_r17->ephemerisInfo_r17->present = NR_EphemerisInfo_r17_PR_positionVelocity_r17;
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 = scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 =
...@@ -528,7 +529,12 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap) ...@@ -528,7 +529,12 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
free(scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17); free(scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17);
scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = NULL; scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = NULL;
} }
if (*scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 == 0) {
free(scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17);
scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 = NULL;
}
if (scc->ext2->ntn_Config_r17->ta_Info_r17->ta_Common_r17 == -1) { if (scc->ext2->ntn_Config_r17->ta_Info_r17->ta_Common_r17 == -1) {
free(scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17);
free(scc->ext2->ntn_Config_r17->ta_Info_r17); free(scc->ext2->ntn_Config_r17->ta_Info_r17);
scc->ext2->ntn_Config_r17->ta_Info_r17 = NULL; scc->ext2->ntn_Config_r17->ta_Info_r17 = NULL;
} }
...@@ -1129,11 +1135,25 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf ...@@ -1129,11 +1135,25 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf
AssertFatal(pcc != NULL && pcc->commonSearchSpaceList == NULL, "memory leak\n"); AssertFatal(pcc != NULL && pcc->commonSearchSpaceList == NULL, "memory leak\n");
pcc->commonSearchSpaceList = calloc_or_fail(1, sizeof(*pcc->commonSearchSpaceList)); pcc->commonSearchSpaceList = calloc_or_fail(1, sizeof(*pcc->commonSearchSpaceList));
NR_SearchSpace_t *ss1 = rrc_searchspace_config(true, 1, 0); // TODO: Make CSS aggregation levels configurable
int css_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
css_num_agg_level_candidates[PDCCH_AGG_LEVEL1] = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
if (get_softmodem_params()->usim_test) {
css_num_agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
css_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
css_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1;
} else {
css_num_agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
css_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
css_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
}
css_num_agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
NR_SearchSpace_t *ss1 = rrc_searchspace_config(true, 1, 0, css_num_agg_level_candidates);
asn1cSeqAdd(&pcc->commonSearchSpaceList->list, ss1); asn1cSeqAdd(&pcc->commonSearchSpaceList->list, ss1);
NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, 2, 0); NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, 2, 0, css_num_agg_level_candidates);
asn1cSeqAdd(&pcc->commonSearchSpaceList->list, ss2); asn1cSeqAdd(&pcc->commonSearchSpaceList->list, ss2);
NR_SearchSpace_t *ss3 = rrc_searchspace_config(true, 3, 0); NR_SearchSpace_t *ss3 = rrc_searchspace_config(true, 3, 0, css_num_agg_level_candidates);
asn1cSeqAdd(&pcc->commonSearchSpaceList->list, ss3); asn1cSeqAdd(&pcc->commonSearchSpaceList->list, ss3);
asn1cCallocOne(pcc->searchSpaceSIB1, 0); asn1cCallocOne(pcc->searchSpaceSIB1, 0);
...@@ -1501,6 +1521,34 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) ...@@ -1501,6 +1521,34 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
} }
} }
// Construct default aggragation level list or read from config
int uess_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
uess_num_agg_level_candidates[PDCCH_AGG_LEVEL1] = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
if (get_softmodem_params()->usim_test) {
uess_num_agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
uess_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
uess_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1;
} else {
uess_num_agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n2;
uess_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n0;
uess_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
}
uess_num_agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
int* agg_level_list = uess_num_agg_level_candidates;
int num_agg_levels = 5;
if (GNBParamList.paramarray[0][GNB_UESS_AGG_LEVEL_LIST_IDX].numelt > 0) {
agg_level_list = GNBParamList.paramarray[0][GNB_UESS_AGG_LEVEL_LIST_IDX].iptr;
num_agg_levels = GNBParamList.paramarray[0][GNB_UESS_AGG_LEVEL_LIST_IDX].numelt;
}
memcpy(config.num_agg_level_candidates, agg_level_list, sizeof(int) * num_agg_levels);
LOG_I(NR_MAC,
"Candidates per PDCCH aggregation level on UESS: L1: %d, L2: %d, L4: %d, L8: %d, L16: %d\n",
config.num_agg_level_candidates[PDCCH_AGG_LEVEL1],
config.num_agg_level_candidates[PDCCH_AGG_LEVEL2],
config.num_agg_level_candidates[PDCCH_AGG_LEVEL4],
config.num_agg_level_candidates[PDCCH_AGG_LEVEL8],
config.num_agg_level_candidates[PDCCH_AGG_LEVEL16]);
NR_ServingCellConfigCommon_t *scc = get_scc_config(cfg, config.minRXTXTIME); NR_ServingCellConfigCommon_t *scc = get_scc_config(cfg, config.minRXTXTIME);
//xer_fprint(stdout, &asn_DEF_NR_ServingCellConfigCommon, scc); //xer_fprint(stdout, &asn_DEF_NR_ServingCellConfigCommon, scc);
NR_ServingCellConfig_t *scd = get_scd_config(cfg); NR_ServingCellConfig_t *scd = get_scd_config(cfg);
......
...@@ -138,6 +138,7 @@ typedef enum { ...@@ -138,6 +138,7 @@ typedef enum {
#define GNB_CONFIG_STRING_NUM_DL_HARQPROCESSES "num_dlharq" #define GNB_CONFIG_STRING_NUM_DL_HARQPROCESSES "num_dlharq"
#define GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES "num_ulharq" #define GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES "num_ulharq"
#define GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST "beam_weights" #define GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST "beam_weights"
#define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels"
#define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n" #define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n"
#define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support" #define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support"
...@@ -148,6 +149,7 @@ typedef enum { ...@@ -148,6 +149,7 @@ typedef enum {
#define GNB_CONFIG_HLP_GNB_CU_UP_ID "defines the gNB-CU-UP ID (only applicable for CU-UP)" #define GNB_CONFIG_HLP_GNB_CU_UP_ID "defines the gNB-CU-UP ID (only applicable for CU-UP)"
#define GNB_CONFIG_HLP_NUM_DL_HARQ "Set Num DL harq processes. Valid values 2,4,6,8,10,12,16,32. Default 16" #define GNB_CONFIG_HLP_NUM_DL_HARQ "Set Num DL harq processes. Valid values 2,4,6,8,10,12,16,32. Default 16"
#define GNB_CONFIG_HLP_NUM_UL_HARQ "Set Num UL harq processes. Valid values 16,32. Default 16" #define GNB_CONFIG_HLP_NUM_UL_HARQ "Set Num UL harq processes. Valid values 16,32. Default 16"
#define GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST "List of aggregation levels with number of candidates per level. Element 0 - aggregation level 1"
/*-----------------------------------------------------------------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* cell configuration parameters */ /* cell configuration parameters */
...@@ -191,6 +193,8 @@ typedef enum { ...@@ -191,6 +193,8 @@ typedef enum {
{GNB_CONFIG_STRING_NUM_DL_HARQPROCESSES, GNB_CONFIG_HLP_NUM_DL_HARQ, 0, .iptr=NULL, .defintval=16, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_NUM_DL_HARQPROCESSES, GNB_CONFIG_HLP_NUM_DL_HARQ, 0, .iptr=NULL, .defintval=16, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES, GNB_CONFIG_HLP_NUM_UL_HARQ, 0, .iptr=NULL, .defintval=16, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES, GNB_CONFIG_HLP_NUM_UL_HARQ, 0, .iptr=NULL, .defintval=16, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST, NULL, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ {GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST, NULL, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \
{GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST, \
GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST, 0, .iptr=NULL, .defintarrayval=NULL, TYPE_INTARRAY, 0}, \
} }
// clang-format on // clang-format on
...@@ -231,6 +235,7 @@ typedef enum { ...@@ -231,6 +235,7 @@ typedef enum {
#define GNB_NUM_DL_HARQ_IDX 33 #define GNB_NUM_DL_HARQ_IDX 33
#define GNB_NUM_UL_HARQ_IDX 34 #define GNB_NUM_UL_HARQ_IDX 34
#define GNB_BEAMWEIGHTS_IDX 35 #define GNB_BEAMWEIGHTS_IDX 35
#define GNB_UESS_AGG_LEVEL_LIST_IDX 36
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32} #define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32}
...@@ -273,6 +278,7 @@ typedef enum { ...@@ -273,6 +278,7 @@ typedef enum {
{ .s1 = { config_check_intval, NUM_DL_HARQ_OKVALUES,8 } }, \ { .s1 = { config_check_intval, NUM_DL_HARQ_OKVALUES,8 } }, \
{ .s1 = { config_check_intval, NUM_UL_HARQ_OKVALUES,2 } }, \ { .s1 = { config_check_intval, NUM_UL_HARQ_OKVALUES,2 } }, \
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
} }
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------*/
......
...@@ -76,8 +76,6 @@ static const uint16_t symbol_ssb_E[64] = {8, 12, 16, 20, 32, 36, 40, 44, ...@@ -76,8 +76,6 @@ static const uint16_t symbol_ssb_E[64] = {8, 12, 16, 20, 32, 36, 40, 44,
288, 292, 296, 300, 312, 316, 320, 324, 344, 348, 352, 356, 368, 372, 376, 380, 288, 292, 296, 300, 312, 316, 320, 324, 344, 348, 352, 356, 368, 372, 376, 380,
400, 404, 408, 412, 424, 428, 432, 436, 456, 460, 464, 468, 480, 484, 488, 492}; 400, 404, 408, 412, 424, 428, 432, 436, 456, 460, 464, 468, 480, 484, 488, 492};
const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz // Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
static const uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0, 13, 15, 18, 22, 26, 32, 38, 46, 59, 76, 93, 119, 167, 279, 419}; static const uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0, 13, 15, 18, 22, 26, 32, 38, 46, 59, 76, 93, 119, 167, 279, 419};
static const uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] = static const uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] =
...@@ -3555,73 +3553,6 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig, long transformPrec ...@@ -3555,73 +3553,6 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig, long transformPrec
} }
} }
static const int tdd_period_to_num[8] = {500, 625, 1000, 1250, 2000, 2500, 5000, 10000};
bool is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slot)
{
if (tdd_UL_DL_ConfigurationCommon == NULL)
return true;
int period1, period2 = 0;
if (tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
period1 = 3000+*tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
else
period1 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity];
if (tdd_UL_DL_ConfigurationCommon->pattern2) {
if (tdd_UL_DL_ConfigurationCommon->pattern2->ext1 &&
tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530)
period2 = 3000 + *tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530;
else
period2 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity];
}
int period = period1+period2;
int scs = tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
int slots = period * (1 << scs) / 1000;
int slots1 = period1 * (1 << scs) / 1000;
int slot_in_period = slot % slots;
if (slot_in_period < slots1)
return slot_in_period <= tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
else
return slot_in_period <= slots1 + tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots;
}
bool is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slot, frame_type_t frame_type)
{
// Note: condition on frame_type
// goal: the UL scheduler assumes mode is TDD therefore this hack is needed to make FDD work
if (frame_type == FDD)
return true;
if (tdd_UL_DL_ConfigurationCommon == NULL)
// before receiving TDD information all slots should be considered to be DL
return false;
int period1, period2 = 0;
if (tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
period1 = 3000 + *tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
else
period1 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity];
if (tdd_UL_DL_ConfigurationCommon->pattern2) {
if (tdd_UL_DL_ConfigurationCommon->pattern2->ext1 &&
tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530)
period2 = 3000 + *tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530;
else
period2 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity];
}
int period = period1+period2;
int scs = tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
int slots = period * (1 << scs) / 1000;
int slots1 = period1 * (1 << scs) / 1000;
int slot_in_period = slot % slots;
if (slot_in_period < slots1)
return slot_in_period >= tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
else
return slot_in_period >= slots1+tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots;
}
int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config, int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,
int dci_format, int dci_format,
int dmrs_TypeA_Position, int dmrs_TypeA_Position,
...@@ -4198,6 +4129,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD ...@@ -4198,6 +4129,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 table 10.1-1 // 38.213 table 10.1-1
/// MUX PATTERN 1 /// MUX PATTERN 1
int slots_per_frame = get_slots_per_frame_from_scs(scs_ssb);
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){ if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){
big_o = table_38213_13_11_c1[index_4lsb]; big_o = table_38213_13_11_c1[index_4lsb];
big_m = table_38213_13_11_c3[index_4lsb]; big_m = table_38213_13_11_c3[index_4lsb];
...@@ -4214,7 +4146,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD ...@@ -4214,7 +4146,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 chapter 13: over two consecutive slots // 38.213 chapter 13: over two consecutive slots
type0_PDCCH_CSS_config->search_space_duration = 2; type0_PDCCH_CSS_config->search_space_duration = 2;
// two frames // two frames
type0_PDCCH_CSS_config->search_space_frame_period = nr_slots_per_frame[scs_ssb]<<1; type0_PDCCH_CSS_config->search_space_frame_period = slots_per_frame << 1;
} }
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){ if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){
...@@ -4235,7 +4167,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD ...@@ -4235,7 +4167,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 chapter 13: over two consecutive slots // 38.213 chapter 13: over two consecutive slots
type0_PDCCH_CSS_config->search_space_duration = 2; type0_PDCCH_CSS_config->search_space_duration = 2;
// two frames // two frames
type0_PDCCH_CSS_config->search_space_frame_period = nr_slots_per_frame[scs_ssb]<<1; type0_PDCCH_CSS_config->search_space_frame_period = slots_per_frame << 1;
} }
/// MUX PATTERN 2 /// MUX PATTERN 2
...@@ -4302,7 +4234,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD ...@@ -4302,7 +4234,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 chapter 13: over one slot // 38.213 chapter 13: over one slot
type0_PDCCH_CSS_config->search_space_duration = 1; type0_PDCCH_CSS_config->search_space_duration = 1;
// SSB periodicity in slots // SSB periodicity in slots
type0_PDCCH_CSS_config->search_space_frame_period = ssb_period*nr_slots_per_frame[scs_ssb]; type0_PDCCH_CSS_config->search_space_frame_period = ssb_period * slots_per_frame;
} }
/// MUX PATTERN 3 /// MUX PATTERN 3
...@@ -4332,7 +4264,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD ...@@ -4332,7 +4264,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 chapter 13: over one slot // 38.213 chapter 13: over one slot
type0_PDCCH_CSS_config->search_space_duration = 1; type0_PDCCH_CSS_config->search_space_duration = 1;
// SSB periodicity in slots // SSB periodicity in slots
type0_PDCCH_CSS_config->search_space_frame_period = ssb_period*nr_slots_per_frame[scs_ssb]; type0_PDCCH_CSS_config->search_space_frame_period = ssb_period * slots_per_frame;
} }
AssertFatal(type0_PDCCH_CSS_config->sfn_c >= 0, ""); AssertFatal(type0_PDCCH_CSS_config->sfn_c >= 0, "");
...@@ -4392,9 +4324,7 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf ...@@ -4392,9 +4324,7 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf
coreset0->pdcch_DMRS_ScramblingID = NULL; coreset0->pdcch_DMRS_ScramblingID = NULL;
} }
void fill_searchSpaceZero(NR_SearchSpace_t *ss0, void fill_searchSpaceZero(NR_SearchSpace_t *ss0, int slots_per_frame, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config)
int slots_per_frame,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config)
{ {
AssertFatal(ss0, "SearchSpace0 should have been allocated outside of this function\n"); AssertFatal(ss0, "SearchSpace0 should have been allocated outside of this function\n");
if(ss0->controlResourceSetId == NULL) if(ss0->controlResourceSetId == NULL)
......
...@@ -63,10 +63,16 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config, ...@@ -63,10 +63,16 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,
int startSymbol, int startSymbol,
mappingType_t mappingtype, mappingType_t mappingtype,
int length); int length);
int get_slots_per_frame_from_scs(int scs);
bool is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP); bool is_ul_slot(const slot_t slot, const frame_structure_t *fs);
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs);
bool is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, frame_type_t frame_type); bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs);
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd);
void config_frame_structure(int mu,
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,
uint8_t tdd_period,
uint8_t frame_type,
frame_structure_t *fs);
uint8_t compute_srs_resource_indicator(long *maxMIMO_Layers, uint8_t compute_srs_resource_indicator(long *maxMIMO_Layers,
NR_PUSCH_Config_t *pusch_Config, NR_PUSCH_Config_t *pusch_Config,
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nr_mac_common.h"
#include "common/utils/nr/nr_common.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
int get_slots_per_frame_from_scs(int scs)
{
const int nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
return nr_slots_per_frame[scs];
}
const float tdd_ms_period_pattern[] = {0.5, 0.625, 1.0, 1.25, 2.0, 2.5, 5.0, 10.0};
const float tdd_ms_period_ext[] = {3.0, 4.0};
/**
* @brief Retrieves the periodicity in milliseconds for the given TDD pattern
* depending on the presence of the extension
* @param pattern Pointer to the NR_TDD_UL_DL_Pattern_t pattern structure
* @return Periodicity value in milliseconds.
*/
static float get_tdd_periodicity(NR_TDD_UL_DL_Pattern_t *pattern)
{
if (!pattern->ext1) {
LOG_D(NR_MAC, "Setting TDD configuration period to dl_UL_TransmissionPeriodicity %ld\n", pattern->dl_UL_TransmissionPeriodicity);
return tdd_ms_period_pattern[pattern->dl_UL_TransmissionPeriodicity];
} else {
DevAssert(pattern->ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL);
LOG_D(NR_MAC,
"Setting TDD configuration period to dl_UL_TransmissionPeriodicity_v1530 %ld\n",
*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530);
return tdd_ms_period_ext[*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530];
}
}
/**
* @brief Determines the TDD period index based on pattern periodicities
* @note Not applicabile to pattern extension
* @param tdd Pointer to the NR_TDD_UL_DL_ConfigCommon_t containing patterns
* @return Index of the TDD period in tdd_ms_period_pattern
*/
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd)
{
int tdd_period_idx = 0;
float pattern1_ms = get_tdd_periodicity(&tdd->pattern1);
float pattern2_ms = tdd->pattern2 ? get_tdd_periodicity(tdd->pattern2) : 0.0;
bool found_match = false;
// Find matching TDD period in the predefined list of periodicities
for (int i = 0; i < NFAPI_MAX_NUM_PERIODS; i++) {
if ((pattern1_ms + pattern2_ms) == tdd_ms_period_pattern[i]) {
tdd_period_idx = i;
LOG_I(NR_MAC,
"TDD period index = %d, based on the sum of dl_UL_TransmissionPeriodicity "
"from Pattern1 (%f ms) and Pattern2 (%f ms): Total = %f ms\n",
tdd_period_idx,
pattern1_ms,
pattern2_ms,
pattern1_ms + pattern2_ms);
found_match = true;
break;
}
}
// Assert if no match was found
AssertFatal(found_match, "The sum of pattern1_ms and pattern2_ms does not match any value in tdd_ms_period_pattern");
return tdd_period_idx;
}
/**
* @brief Configures the TDD period, including bitmap, in the frame structure
*
* This function sets the TDD period configuration for DL, UL, and mixed slots in
* the specified frame structure instance, according to the given pattern, and
* updates the bitmap.
*
* @param pattern NR_TDD_UL_DL_Pattern_t configuration containing TDD slots and symbols configuration
* @param fs frame_structure_t pointer
* @param curr_total_slot current position in the slot bitmap to start from
*
* @return Number of slots in the configured TDD period
*/
static uint8_t set_tdd_bmap_period(NR_TDD_UL_DL_Pattern_t *pattern, tdd_period_config_t *pc, int8_t curr_total_slot)
{
int8_t n_dl_slot = pattern->nrofDownlinkSlots;
int8_t n_ul_slot = pattern->nrofUplinkSlots;
int8_t n_dl_symbols = pattern->nrofDownlinkSymbols;
int8_t n_ul_symbols = pattern->nrofUplinkSymbols;
// Total slots in the period: if DL/UL symbols are present, is mixed slot
const bool has_mixed_slot = (n_ul_symbols + n_dl_symbols) > 0;
int8_t total_slot = has_mixed_slot ? n_dl_slot + n_ul_slot + 1 : n_dl_slot + n_ul_slot;
/** Update TDD period configuration:
* mixed slots with DL symbols are counted as DL slots
* mixed slots with UL symbols are counted as UL slots */
pc->num_dl_slots += (n_dl_slot + (n_dl_symbols > 0));
pc->num_ul_slots += (n_ul_slot + (n_ul_symbols > 0));
// Populate the slot bitmap for each slot in the TDD period
for (int i = 0; i < total_slot; i++) {
tdd_bitmap_t *bitmap = &pc->tdd_slot_bitmap[i + curr_total_slot];
if (i < n_dl_slot)
bitmap->slot_type = TDD_NR_DOWNLINK_SLOT;
else if ((i == n_dl_slot) && has_mixed_slot) {
bitmap->slot_type = TDD_NR_MIXED_SLOT;
bitmap->num_dl_symbols = n_dl_symbols;
bitmap->num_ul_symbols = n_ul_symbols;
} else if (n_ul_slot)
bitmap->slot_type = TDD_NR_UPLINK_SLOT;
}
LOG_I(NR_MAC,
"Set TDD configuration period to: %d DL slots, %d UL slots, %d slots per period (NR_TDD_UL_DL_Pattern is %d DL slots, %d "
"UL slots, %d DL symbols, %d UL symbols)\n",
pc->num_dl_slots,
pc->num_ul_slots,
total_slot,
n_dl_slot,
n_ul_slot,
n_dl_symbols,
n_ul_symbols);
return total_slot;
}
/**
* @brief Configures TDD patterns (1 or 2) in the frame structure
*
* This function sets up the TDD configuration in the frame structure by applying
* DL and UL patterns as defined in NR_TDD_UL_DL_ConfigCommon.
* It handles both TDD pattern1 and pattern2.
*
* @param tdd NR_TDD_UL_DL_ConfigCommon_t pointer containing pattern1 and pattern2
* @param fs Pointer to the frame structure to update with the configured TDD patterns.
*
* @return void
*/
static void config_tdd_patterns(NR_TDD_UL_DL_ConfigCommon_t *tdd, frame_structure_t *fs)
{
int num_of_patterns = 1;
uint8_t nb_slots_p2 = 0;
// Reset num dl/ul slots
tdd_period_config_t *pc = &fs->period_cfg;
pc->num_dl_slots = 0;
pc->num_ul_slots = 0;
// Pattern1
uint8_t nb_slots_p1 = set_tdd_bmap_period(&tdd->pattern1, pc, 0);
// Pattern2
if (tdd->pattern2) {
num_of_patterns++;
nb_slots_p2 = set_tdd_bmap_period(tdd->pattern2, pc, nb_slots_p1);
}
LOG_I(NR_MAC,
"Configured %d TDD patterns (total slots: pattern1 = %d, pattern2 = %d)\n",
num_of_patterns,
nb_slots_p1,
nb_slots_p2);
}
/**
* @brief Configures the frame structure and the NFAPI config request
* depending on the duplex mode. If TDD, does the TDD patterns
* and TDD periods configuration.
*
* @param mu numerology
* @param scc pointer to scc
* @param tdd_period TDD period
* @param frame_type type of frame structure (FDD or TDD)
* @param fs pointer to the frame structure to update
*/
void config_frame_structure(int mu,
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,
uint8_t tdd_period,
uint8_t frame_type,
frame_structure_t *fs)
{
fs->numb_slots_frame = get_slots_per_frame_from_scs(mu);
fs->frame_type = frame_type;
if (frame_type == TDD) {
fs->numb_period_frame = get_nb_periods_per_frame(tdd_period);
fs->numb_slots_period = fs->numb_slots_frame / fs->numb_period_frame;
config_tdd_patterns(tdd_UL_DL_ConfigurationCommon, fs);
} else { // FDD
fs->numb_period_frame = 1;
fs->numb_slots_period = fs->numb_slots_frame;
}
AssertFatal(fs->numb_period_frame > 0, "Frame configuration cannot be configured!\n");
}
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with UL symbols
* (3) Full UL slot
*/
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs)
{
if (fs->frame_type == FDD)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_ul_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_UPLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with DL symbols
* (3) Full DL slot
*/
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs)
{
if (fs->frame_type == FDD)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_dl_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_DOWNLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) Mixed slot with DL and/or UL symbols
*/
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs)
{
if (fs->frame_type == FDD)
return false;
slot_t s = get_slot_idx_in_period(slot, fs);
const tdd_period_config_t *pc = &fs->period_cfg;
return pc->tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT;
}
...@@ -37,8 +37,6 @@ ...@@ -37,8 +37,6 @@
/*#include "PHY/defs_common.h"*/ /*#include "PHY/defs_common.h"*/
extern const uint8_t nr_slots_per_frame[5];
/* Scheduler */ /* Scheduler */
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
extern uint8_t nfapi_mode; extern uint8_t nfapi_mode;
......
This diff is collapsed.
...@@ -165,7 +165,7 @@ ...@@ -165,7 +165,7 @@
// Define the UE L2 states with X-Macro // Define the UE L2 states with X-Macro
#define NR_UE_L2_STATES \ #define NR_UE_L2_STATES \
UE_STATE(UE_NOT_SYNC) \ UE_STATE(UE_NOT_SYNC) \
UE_STATE(UE_SYNC) \ UE_STATE(UE_RECEIVING_SIB) \
UE_STATE(UE_PERFORMING_RA) \ UE_STATE(UE_PERFORMING_RA) \
UE_STATE(UE_CONNECTED) \ UE_STATE(UE_CONNECTED) \
UE_STATE(UE_DETACHING) UE_STATE(UE_DETACHING)
...@@ -554,9 +554,9 @@ typedef struct { ...@@ -554,9 +554,9 @@ typedef struct {
} si_schedInfo_t; } si_schedInfo_t;
typedef struct ntn_timing_advance_components { typedef struct ntn_timing_advance_components {
// N_common_ta_adj represents common propagation delay received in SIB19 (ms) // N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms)
double N_common_ta_adj; double N_common_ta_adj;
// N_UE_TA_adj calculated propagation delay from UE and SAT (ms) // N_UE_TA_adj calculated round-trip-time between UE and SAT (ms)
double N_UE_TA_adj; double N_UE_TA_adj;
// drift rate of common ta in µs/s // drift rate of common ta in µs/s
double ntn_ta_commondrift; double ntn_ta_commondrift;
...@@ -599,7 +599,7 @@ typedef struct NR_UE_MAC_INST_s { ...@@ -599,7 +599,7 @@ typedef struct NR_UE_MAC_INST_s {
NR_UL_TIME_ALIGNMENT_t ul_time_alignment; NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon; NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
frame_type_t frame_type; frame_structure_t frame_structure;
/* Random Access */ /* Random Access */
/// CRNTI /// CRNTI
...@@ -682,7 +682,7 @@ static inline int GET_NTN_UE_K_OFFSET(const ntn_timing_advance_componets_t *ntn_ ...@@ -682,7 +682,7 @@ static inline int GET_NTN_UE_K_OFFSET(const ntn_timing_advance_componets_t *ntn_
static inline double GET_COMPLETE_TIME_ADVANCE_MS(const ntn_timing_advance_componets_t *ntn_ta) static inline double GET_COMPLETE_TIME_ADVANCE_MS(const ntn_timing_advance_componets_t *ntn_ta)
{ {
return (ntn_ta->N_common_ta_adj + ntn_ta->N_UE_TA_adj) * 2; return ntn_ta->N_common_ta_adj + ntn_ta->N_UE_TA_adj;
} }
static inline long GET_DURATION_RX_TO_TX(const ntn_timing_advance_componets_t *ntn_ta) static inline long GET_DURATION_RX_TO_TX(const ntn_timing_advance_componets_t *ntn_ta)
......
...@@ -85,10 +85,10 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, ...@@ -85,10 +85,10 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id,
NR_MIB_t *mibP, NR_MIB_t *mibP,
int sched_sib1); int sched_sib1);
void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1); void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1, bool can_start_ra);
struct position; /* forward declaration */ struct position; /* forward declaration */
void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19_r17); void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19_r17, bool can_start_ra);
void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause); void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause);
...@@ -367,7 +367,7 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p ...@@ -367,7 +367,7 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac); void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac);
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs); void ue_init_config_request(NR_UE_MAC_INST_t *mac, int slots_per_frame);
fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot); fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot);
...@@ -376,7 +376,6 @@ void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu); ...@@ -376,7 +376,6 @@ void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu);
fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx); fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx);
void release_ul_config(fapi_nr_ul_config_request_pdu_t *pdu, bool clearIt); void release_ul_config(fapi_nr_ul_config_request_pdu_t *pdu, bool clearIt);
void clear_ul_config_request(NR_UE_MAC_INST_t *mac, int scs);
int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm); int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm);
// PUSCH scheduler: // PUSCH scheduler:
......
...@@ -94,7 +94,7 @@ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac) ...@@ -94,7 +94,7 @@ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
// sf80 default for retxBSR_Timer sf10 for periodicBSR_Timer // sf80 default for retxBSR_Timer sf10 for periodicBSR_Timer
int mu = mac->current_UL_BWP ? mac->current_UL_BWP->scs : get_softmodem_params()->numerology; int mu = mac->current_UL_BWP ? mac->current_UL_BWP->scs : get_softmodem_params()->numerology;
int subframes_per_slot = nr_slots_per_frame[mu] / 10; int subframes_per_slot = get_slots_per_frame_from_scs(mu) / 10;
nr_timer_setup(&mac->scheduling_info.retxBSR_Timer, 80 * subframes_per_slot, 1); // 1 slot update rate nr_timer_setup(&mac->scheduling_info.retxBSR_Timer, 80 * subframes_per_slot, 1); // 1 slot update rate
nr_timer_setup(&mac->scheduling_info.periodicBSR_Timer, 10 * subframes_per_slot, 1); // 1 slot update rate nr_timer_setup(&mac->scheduling_info.periodicBSR_Timer, 10 * subframes_per_slot, 1); // 1 slot update rate
...@@ -139,7 +139,7 @@ NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst) ...@@ -139,7 +139,7 @@ NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst)
nr_ue_init_mac(mac); nr_ue_init_mac(mac);
nr_ue_mac_default_configs(mac); nr_ue_mac_default_configs(mac);
if (IS_SA_MODE(get_softmodem_params())) if (IS_SA_MODE(get_softmodem_params()))
ue_init_config_request(mac, get_softmodem_params()->numerology); ue_init_config_request(mac, get_slots_per_frame_from_scs(get_softmodem_params()->numerology));
} }
int rc = rlc_module_init(0); int rc = rlc_module_init(0);
......
...@@ -84,7 +84,7 @@ void init_RA(NR_UE_MAC_INST_t *mac, ...@@ -84,7 +84,7 @@ void init_RA(NR_UE_MAC_INST_t *mac,
// PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) // PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1)
prach_resources->RA_PCMAX = nr_get_Pcmax(mac->p_Max, prach_resources->RA_PCMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band, mac->nr_band,
mac->frame_type, mac->frame_structure.frame_type,
mac->frequency_range, mac->frequency_range,
mac->current_UL_BWP->channel_bandwidth, mac->current_UL_BWP->channel_bandwidth,
2, 2,
...@@ -617,8 +617,7 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s ...@@ -617,8 +617,7 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon; NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta); const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta);
const int mu = mac->current_UL_BWP->scs; const int slots_per_ms = mac->frame_structure.numb_slots_frame / 10;
const int slots_per_ms = nr_slots_per_frame[mu] / 10;
// start contention resolution timer // start contention resolution timer
const int RA_contention_resolution_timer_ms = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) << 3; const int RA_contention_resolution_timer_ms = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) << 3;
...@@ -914,14 +913,12 @@ int16_t nr_get_RA_window_4Step(const NR_RACH_ConfigCommon_t *rach_ConfigCommon) ...@@ -914,14 +913,12 @@ int16_t nr_get_RA_window_4Step(const NR_RACH_ConfigCommon_t *rach_ConfigCommon)
void nr_get_RA_window(NR_UE_MAC_INST_t *mac) void nr_get_RA_window(NR_UE_MAC_INST_t *mac)
{ {
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__); AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta); const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta);
const int mu = mac->current_DL_BWP->scs; int slots_per_frame = mac->frame_structure.numb_slots_frame;
const int slots_per_ms = nr_slots_per_frame[mu] / 10; const int slots_per_ms = slots_per_frame / 10;
const int ra_Offset_slots = ra->RA_offset * slots_per_frame;
const int ra_Offset_slots = ra->RA_offset * nr_slots_per_frame[mu];
const int ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_ms); const int ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_ms);
ra->RA_window_cnt = ra_Offset_slots + ta_Common_slots; // taking into account the 2 frames gap introduced by OAI gNB ra->RA_window_cnt = ra_Offset_slots + ta_Common_slots; // taking into account the 2 frames gap introduced by OAI gNB
...@@ -1041,7 +1038,7 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr ...@@ -1041,7 +1038,7 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr
void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac) void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac)
{ {
LOG_W(NR_MAC, "Triggering new RA procedure for UE with RNTI %x\n", mac->crnti); LOG_W(NR_MAC, "Triggering new RA procedure for UE with RNTI %x\n", mac->crnti);
mac->state = UE_SYNC; mac->state = UE_PERFORMING_RA;
reset_ra(mac, false); reset_ra(mac, false);
mac->ra.msg3_C_RNTI = true; mac->ra.msg3_C_RNTI = true;
} }
......
...@@ -515,7 +515,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl ...@@ -515,7 +515,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
NR_BWP_Id_t dl_bwp_id = current_DL_BWP ? current_DL_BWP->bwp_id : 0; NR_BWP_Id_t dl_bwp_id = current_DL_BWP ? current_DL_BWP->bwp_id : 0;
NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[dl_bwp_id]; NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[dl_bwp_id];
int scs = current_DL_BWP ? current_DL_BWP->scs : get_softmodem_params()->numerology; int scs = current_DL_BWP ? current_DL_BWP->scs : get_softmodem_params()->numerology;
const int slots_per_frame = nr_slots_per_frame[scs]; const int slots_per_frame = get_slots_per_frame_from_scs(scs);
if (mac->get_sib1) { if (mac->get_sib1) {
int ssb_sc_offset_norm; int ssb_sc_offset_norm;
if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1) if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1)
......
...@@ -347,7 +347,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, ...@@ -347,7 +347,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
// modulated CP-OFDM of equivalent RB allocation. // modulated CP-OFDM of equivalent RB allocation.
int P_CMAX = nr_get_Pcmax(mac->p_Max, int P_CMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band, mac->nr_band,
mac->frame_type, mac->frame_structure.frame_type,
mac->frequency_range, mac->frequency_range,
current_UL_BWP->channel_bandwidth, current_UL_BWP->channel_bandwidth,
2, 2,
...@@ -529,7 +529,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, ...@@ -529,7 +529,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
int M_pusch_component = 10 * log10((pow(2, mu)) * num_rb); int M_pusch_component = 10 * log10((pow(2, mu)) * num_rb);
int P_CMAX = nr_get_Pcmax(mac->p_Max, int P_CMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band, mac->nr_band,
mac->frame_type, mac->frame_structure.frame_type,
mac->frequency_range, mac->frequency_range,
mac->current_UL_BWP->channel_bandwidth, mac->current_UL_BWP->channel_bandwidth,
qm, qm,
...@@ -619,7 +619,7 @@ int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac, ...@@ -619,7 +619,7 @@ int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac,
// allocation. // allocation.
int P_CMAX = nr_get_Pcmax(mac->p_Max, int P_CMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band, mac->nr_band,
mac->frame_type, mac->frame_structure.frame_type,
mac->frequency_range, mac->frequency_range,
mac->current_UL_BWP->channel_bandwidth, mac->current_UL_BWP->channel_bandwidth,
2, 2,
......
...@@ -223,10 +223,14 @@ void nr_ue_decode_mib(NR_UE_MAC_INST_t *mac, int cc_id) ...@@ -223,10 +223,14 @@ void nr_ue_decode_mib(NR_UE_MAC_INST_t *mac, int cc_id)
if (mac->first_sync_frame == -1) if (mac->first_sync_frame == -1)
mac->first_sync_frame = frame; mac->first_sync_frame = frame;
if(get_softmodem_params()->phy_test) if (get_softmodem_params()->phy_test)
mac->state = UE_CONNECTED; mac->state = UE_CONNECTED;
else if(mac->state == UE_NOT_SYNC) else if (mac->state == UE_NOT_SYNC) {
mac->state = UE_SYNC; if (IS_SA_MODE(get_softmodem_params()) && mac->get_sib1)
mac->state = UE_RECEIVING_SIB;
else
mac->state = UE_PERFORMING_RA;
}
} }
static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu, static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu,
...@@ -235,6 +239,7 @@ static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsc ...@@ -235,6 +239,7 @@ static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsc
int frame, int frame,
int slot, int slot,
int mu, int mu,
int slots_per_frame,
NR_PDSCH_Config_t *pdsch_config) NR_PDSCH_Config_t *pdsch_config)
{ {
// only for C-RNTI, MCS-C-RNTI, CS-RNTI (and only C-RNTI is supported for now) // only for C-RNTI, MCS-C-RNTI, CS-RNTI (and only C-RNTI is supported for now)
...@@ -258,7 +263,7 @@ static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsc ...@@ -258,7 +263,7 @@ static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsc
AssertFatal(zp_res->periodicityAndOffset, "periodicityAndOffset cannot be null for periodic ZP resource\n"); AssertFatal(zp_res->periodicityAndOffset, "periodicityAndOffset cannot be null for periodic ZP resource\n");
int period, offset; int period, offset;
csi_period_offset(NULL, zp_res->periodicityAndOffset, &period, &offset); csi_period_offset(NULL, zp_res->periodicityAndOffset, &period, &offset);
if((frame * nr_slots_per_frame[mu] + slot - offset) % period != 0) if((frame * slots_per_frame + slot - offset) % period != 0)
continue; continue;
AssertFatal(dlsch_pdu->numCsiRsForRateMatching < NFAPI_MAX_NUM_CSI_RATEMATCH, "csiRsForRateMatching out of bounds\n"); AssertFatal(dlsch_pdu->numCsiRsForRateMatching < NFAPI_MAX_NUM_CSI_RATEMATCH, "csiRsForRateMatching out of bounds\n");
fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu = &dlsch_pdu->csiRsForRateMatching[dlsch_pdu->numCsiRsForRateMatching]; fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu = &dlsch_pdu->csiRsForRateMatching[dlsch_pdu->numCsiRsForRateMatching];
...@@ -705,7 +710,8 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, ...@@ -705,7 +710,8 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
} }
dlsch_pdu->numCsiRsForRateMatching = 0; dlsch_pdu->numCsiRsForRateMatching = 0;
configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, dlsch_pdu->SubcarrierSpacing, pdsch_config); int slots_frame = mac->frame_structure.numb_slots_frame;
configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, dlsch_pdu->SubcarrierSpacing, slots_frame, pdsch_config);
/* IDENTIFIER_DCI_FORMATS */ /* IDENTIFIER_DCI_FORMATS */
...@@ -1034,7 +1040,8 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac, ...@@ -1034,7 +1040,8 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
nr_rnti_type_t rnti_type = get_rnti_type(mac, dci_ind->rnti); nr_rnti_type_t rnti_type = get_rnti_type(mac, dci_ind->rnti);
dlsch_pdu->numCsiRsForRateMatching = 0; dlsch_pdu->numCsiRsForRateMatching = 0;
configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, current_DL_BWP->scs, pdsch_Config); int slots_frame = mac->frame_structure.numb_slots_frame;
configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, current_DL_BWP->scs, slots_frame, pdsch_Config);
/* IDENTIFIER_DCI_FORMATS */ /* IDENTIFIER_DCI_FORMATS */
/* CARRIER_IND */ /* CARRIER_IND */
...@@ -1468,8 +1475,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, ...@@ -1468,8 +1475,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
current_harq->dai_cumul = 0; current_harq->dai_cumul = 0;
current_harq->delta_pucch = delta_pucch; current_harq->delta_pucch = delta_pucch;
// FIXME k0 != 0 currently not taken into consideration // FIXME k0 != 0 currently not taken into consideration
int scs = mac->current_DL_BWP ? mac->current_DL_BWP->scs : get_softmodem_params()->numerology; int slots_per_frame = mac->frame_structure.numb_slots_frame;
int slots_per_frame = nr_slots_per_frame[scs];
current_harq->ul_frame = frame; current_harq->ul_frame = frame;
current_harq->ul_slot = slot + data_toul_fb; current_harq->ul_slot = slot + data_toul_fb;
if (current_harq->ul_slot >= slots_per_frame) { if (current_harq->ul_slot >= slots_per_frame) {
...@@ -1532,8 +1538,7 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, ...@@ -1532,8 +1538,7 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
long *pusch_id = NULL; long *pusch_id = NULL;
long *id0 = NULL; long *id0 = NULL;
const int scs = current_UL_BWP->scs; const int scs = current_UL_BWP->scs;
int subframe_number = slot / (mac->frame_structure.numb_slots_frame / 10);
int subframe_number = slot / (nr_slots_per_frame[scs]/10);
pucch_pdu->rnti = rnti; pucch_pdu->rnti = rnti;
LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource); LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource);
...@@ -2503,7 +2508,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p ...@@ -2503,7 +2508,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p
int SR_period; int SR_offset; int SR_period; int SR_offset;
find_period_offset_SR(sr_Config, &SR_period, &SR_offset); find_period_offset_SR(sr_Config, &SR_period, &SR_offset);
const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; const int n_slots_frame = mac->frame_structure.numb_slots_frame;
int sfn_sf = frame * n_slots_frame + slot; int sfn_sf = frame * n_slots_frame + slot;
if ((sfn_sf - SR_offset) % SR_period == 0) { if ((sfn_sf - SR_offset) % SR_period == 0) {
...@@ -2613,7 +2618,7 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC ...@@ -2613,7 +2618,7 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC
if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic) { if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic) {
int period, offset; int period, offset;
csi_period_offset(csirep, NULL, &period, &offset); csi_period_offset(csirep, NULL, &period, &offset);
const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; const int n_slots_frame = mac->frame_structure.numb_slots_frame;
if (((n_slots_frame*frame + slot - offset)%period) == 0 && pucch_Config) { if (((n_slots_frame*frame + slot - offset)%period) == 0 && pucch_Config) {
int csi_res_id = -1; int csi_res_id = -1;
for (int i = 0; i < csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.count; i++) { for (int i = 0; i < csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.count; i++) {
...@@ -3433,12 +3438,10 @@ static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, in ...@@ -3433,12 +3438,10 @@ static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, in
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment; NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
ul_time_alignment->ta_command = ta; ul_time_alignment->ta_command = ta;
ul_time_alignment->ta_apply = type; ul_time_alignment->ta_apply = type;
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs); const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
const int n_slots_frame = nr_slots_per_frame[mac->current_UL_BWP->scs]; const int n_slots_frame = mac->frame_structure.numb_slots_frame;
ul_time_alignment->frame = (frame + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER; ul_time_alignment->frame = (frame + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER;
ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame; ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame;
// start or restart the timeAlignmentTimer associated with the indicated TAG // start or restart the timeAlignmentTimer associated with the indicated TAG
nr_timer_start(&mac->time_alignment_timer); nr_timer_start(&mac->time_alignment_timer);
} }
......
This diff is collapsed.
...@@ -175,15 +175,9 @@ uint8_t sl_determine_if_SSB_slot(uint16_t frame, uint16_t slot, uint16_t slots_p ...@@ -175,15 +175,9 @@ uint8_t sl_determine_if_SSB_slot(uint16_t frame, uint16_t slot, uint16_t slots_p
return 0; return 0;
} }
static uint8_t sl_psbch_scheduler(sl_nr_ue_mac_params_t *sl_mac_params, int ue_id, int frame, int slot) static uint8_t sl_psbch_scheduler(sl_nr_ue_mac_params_t *sl_mac_params, int ue_id, int frame, int slot, int slots_per_frame)
{ {
uint8_t config_type = 0, is_psbch_rx_slot = 0, is_psbch_tx_slot = 0; uint8_t config_type = 0, is_psbch_rx_slot = 0, is_psbch_tx_slot = 0;
sl_nr_phy_config_request_t *sl_cfg = &sl_mac_params->sl_phy_config.sl_config_req;
uint16_t scs = sl_cfg->sl_bwp_config.sl_scs;
uint16_t slots_per_frame = nr_slots_per_frame[scs];
if (sl_mac_params->rx_sl_bch.status) { if (sl_mac_params->rx_sl_bch.status) {
is_psbch_rx_slot = sl_determine_if_SSB_slot(frame, slot, slots_per_frame, &sl_mac_params->rx_sl_bch); is_psbch_rx_slot = sl_determine_if_SSB_slot(frame, slot, slots_per_frame, &sl_mac_params->rx_sl_bch);
...@@ -259,16 +253,9 @@ static void sl_adjust_indices_based_on_timing(sl_nr_ue_mac_params_t *sl_mac, ...@@ -259,16 +253,9 @@ static void sl_adjust_indices_based_on_timing(sl_nr_ue_mac_params_t *sl_mac,
} }
// Adjust indices as new timing is acquired // Adjust indices as new timing is acquired
static void sl_actions_after_new_timing(sl_nr_ue_mac_params_t *sl_mac, static void sl_actions_after_new_timing(sl_nr_ue_mac_params_t *sl_mac, int ue_id, int frame, int slot, int slots_per_frame)
int ue_id,
int frame, int slot)
{ {
uint8_t mu = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
uint8_t slots_per_frame = nr_slots_per_frame[mu];
sl_determine_slot_bitmap(sl_mac, ue_id); sl_determine_slot_bitmap(sl_mac, ue_id);
sl_mac->N_SL_SLOTS = sl_determine_num_sidelink_slots(sl_mac, ue_id, &sl_mac->N_SSB_16frames); sl_mac->N_SL_SLOTS = sl_determine_num_sidelink_slots(sl_mac, ue_id, &sl_mac->N_SSB_16frames);
sl_adjust_indices_based_on_timing(sl_mac, ue_id, frame, slot, slots_per_frame); sl_adjust_indices_based_on_timing(sl_mac, ue_id, frame, slot, slots_per_frame);
} }
...@@ -385,7 +372,7 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t ...@@ -385,7 +372,7 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t
// Adjust indices as new timing is acquired // Adjust indices as new timing is acquired
if (sl_mac->timing_acquired) { if (sl_mac->timing_acquired) {
sl_actions_after_new_timing(sl_mac, ue_id, sl_ind->frame_tx, sl_ind->slot_tx); sl_actions_after_new_timing(sl_mac, ue_id, sl_ind->frame_tx, sl_ind->slot_tx, mac->frame_structure.numb_slots_frame);
sl_mac->timing_acquired = false; sl_mac->timing_acquired = false;
} }
...@@ -399,7 +386,7 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t ...@@ -399,7 +386,7 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t
uint8_t tti_action = 0; uint8_t tti_action = 0;
// Check if PSBCH slot and PSBCH should be transmitted or Received // Check if PSBCH slot and PSBCH should be transmitted or Received
tti_action = sl_psbch_scheduler(sl_mac, ue_id, frame, slot); tti_action = sl_psbch_scheduler(sl_mac, ue_id, frame, slot, mac->frame_structure.numb_slots_frame);
#if 0 // To be expanded later #if 0 // To be expanded later
// TBD .. Check for Actions coming out of TX resource pool // TBD .. Check for Actions coming out of TX resource pool
......
...@@ -92,7 +92,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch) ...@@ -92,7 +92,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
pucch_Config.pucch_PowerControl = &power_config; pucch_Config.pucch_PowerControl = &power_config;
mac.G_b_f_c = 0; mac.G_b_f_c = 0;
mac.pucch_power_control_initialized = true; mac.pucch_power_control_initialized = true;
mac.frame_type = TDD; mac.frame_structure.frame_type = TDD;
int scs = 1; int scs = 1;
int sum_delta_pucch = 3; int sum_delta_pucch = 3;
...@@ -106,7 +106,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch) ...@@ -106,7 +106,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
uint16_t start_prb = 0; uint16_t start_prb = 0;
int P_CMAX = nr_get_Pcmax(23, int P_CMAX = nr_get_Pcmax(23,
mac.nr_band, mac.nr_band,
mac.frame_type, mac.frame_structure.frame_type,
FR1, FR1,
current_UL_BWP.channel_bandwidth, current_UL_BWP.channel_bandwidth,
2, 2,
...@@ -201,7 +201,7 @@ TEST(pusch_power_control, pusch_power_control_msg3) ...@@ -201,7 +201,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
pusch_Config.pusch_PowerControl = &pusch_PowerControl; pusch_Config.pusch_PowerControl = &pusch_PowerControl;
pusch_PowerControl.tpc_Accumulation = (long*)1; pusch_PowerControl.tpc_Accumulation = (long*)1;
mac.pusch_power_control_initialized = true; mac.pusch_power_control_initialized = true;
mac.frame_type = TDD; mac.frame_structure.frame_type = TDD;
// msg3 cofiguration as in 5g_rfsimulator testcase // msg3 cofiguration as in 5g_rfsimulator testcase
int num_rb = 8; int num_rb = 8;
...@@ -218,7 +218,7 @@ TEST(pusch_power_control, pusch_power_control_msg3) ...@@ -218,7 +218,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
int P_CMAX = nr_get_Pcmax(23, int P_CMAX = nr_get_Pcmax(23,
mac.nr_band, mac.nr_band,
mac.frame_type, mac.frame_structure.frame_type,
FR1, FR1,
current_UL_BWP.channel_bandwidth, current_UL_BWP.channel_bandwidth,
Qm, Qm,
...@@ -294,7 +294,7 @@ TEST(pusch_power_control, pusch_power_data) ...@@ -294,7 +294,7 @@ TEST(pusch_power_control, pusch_power_data)
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
mac.nr_band = 78; mac.nr_band = 78;
mac.frame_type = TDD; mac.frame_structure.frame_type = TDD;
bool is_rar_tx_retx = false; bool is_rar_tx_retx = false;
int num_rb = 5; int num_rb = 5;
...@@ -319,7 +319,7 @@ TEST(pusch_power_control, pusch_power_data) ...@@ -319,7 +319,7 @@ TEST(pusch_power_control, pusch_power_data)
int P_CMAX = nr_get_Pcmax(23, int P_CMAX = nr_get_Pcmax(23,
mac.nr_band, mac.nr_band,
mac.frame_type, mac.frame_structure.frame_type,
FR1, FR1,
current_UL_BWP.channel_bandwidth, current_UL_BWP.channel_bandwidth,
Qm, Qm,
...@@ -444,11 +444,11 @@ TEST(pusch_power_control, pusch_power_control_state) ...@@ -444,11 +444,11 @@ TEST(pusch_power_control, pusch_power_control_state)
pusch_Config.pusch_PowerControl = &pusch_PowerControl; pusch_Config.pusch_PowerControl = &pusch_PowerControl;
long p0_NominalWithGrant = 0; long p0_NominalWithGrant = 0;
current_UL_BWP.p0_NominalWithGrant = &p0_NominalWithGrant; current_UL_BWP.p0_NominalWithGrant = &p0_NominalWithGrant;
mac.frame_type = TDD; mac.frame_structure.frame_type = TDD;
int P_CMAX = nr_get_Pcmax(23, int P_CMAX = nr_get_Pcmax(23,
mac.nr_band, mac.nr_band,
mac.frame_type, mac.frame_structure.frame_type,
FR1, FR1,
current_UL_BWP.channel_bandwidth, current_UL_BWP.channel_bandwidth,
Qm, Qm,
......
...@@ -96,7 +96,7 @@ TEST(test_init_ra, four_step_cbra) ...@@ -96,7 +96,7 @@ TEST(test_init_ra, four_step_cbra)
nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs; nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs;
mac.p_Max = 23; mac.p_Max = 23;
mac.nr_band = 78; mac.nr_band = 78;
mac.frame_type = TDD; mac.frame_structure.frame_type = TDD;
mac.frequency_range = FR1; mac.frequency_range = FR1;
init_RA(&mac, &prach_resources, &nr_rach_ConfigCommon, &rach_ConfigGeneric, rach_ConfigDedicated); init_RA(&mac, &prach_resources, &nr_rach_ConfigCommon, &rach_ConfigGeneric, rach_ConfigDedicated);
...@@ -121,7 +121,7 @@ TEST(test_init_ra, four_step_cfra) ...@@ -121,7 +121,7 @@ TEST(test_init_ra, four_step_cfra)
nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs; nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs;
mac.p_Max = 23; mac.p_Max = 23;
mac.nr_band = 78; mac.nr_band = 78;
mac.frame_type = TDD; mac.frame_structure.frame_type = TDD;
mac.frequency_range = FR1; mac.frequency_range = FR1;
NR_RACH_ConfigDedicated_t rach_ConfigDedicated = {0}; NR_RACH_ConfigDedicated_t rach_ConfigDedicated = {0};
......
This diff is collapsed.
...@@ -64,10 +64,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB, ...@@ -64,10 +64,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
nfapi_nr_ul_dci_request_t *UL_dci_req) nfapi_nr_ul_dci_request_t *UL_dci_req)
{ {
/* called below and in simulators, so we assume a lock but don't require it */ /* called below and in simulators, so we assume a lock but don't require it */
const int num_slots = gNB->frame_structure.numb_slots_frame;
NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon;
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
UL_tti_req_ahead_initialization(gNB, num_slots, CC_idP, frameP, slotP); UL_tti_req_ahead_initialization(gNB, num_slots, CC_idP, frameP, slotP);
nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP]; nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP];
...@@ -103,14 +100,13 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB, ...@@ -103,14 +100,13 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
TX_req[CC_idP].Number_of_PDUs = 0; TX_req[CC_idP].Number_of_PDUs = 0;
} }
void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int mu) static void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame)
{ {
// for now we use the same logic of UL_tti_req_ahead // for now we use the same logic of UL_tti_req_ahead
// reset after 1 frame with the exception of 15kHz // reset after 1 frame with the exception of 15kHz
if(!beam_info->beam_allocation) if(!beam_info->beam_allocation)
return; return;
// initialization done only once // initialization done only once
const int slots_per_frame = nr_slots_per_frame[mu];
AssertFatal(beam_info->beam_allocation_size >= 0, "Beam information not initialized\n"); AssertFatal(beam_info->beam_allocation_size >= 0, "Beam information not initialized\n");
int idx_to_clear = (frame * slots_per_frame + slot) / beam_info->beam_duration; int idx_to_clear = (frame * slots_per_frame + slot) / beam_info->beam_duration;
idx_to_clear = (idx_to_clear + beam_info->beam_allocation_size - 1) % beam_info->beam_allocation_size; idx_to_clear = (idx_to_clear + beam_info->beam_allocation_size - 1) % beam_info->beam_allocation_size;
...@@ -122,51 +118,6 @@ void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int ...@@ -122,51 +118,6 @@ void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int
} }
} }
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with UL symbols
* (3) Full UL slot
*/
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs)
{
if (!fs->is_tdd)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_ul_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_UPLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with DL symbols
* (3) Full DL slot
*/
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs)
{
if (!fs->is_tdd)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_dl_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_DOWNLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) Mixed slot with DL and/or UL symbols
*/
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs)
{
if (!fs->is_tdd)
return false;
slot_t s = get_slot_idx_in_period(slot, fs);
const tdd_period_config_t *pc = &fs->period_cfg;
return pc->tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT;
}
/* the structure nfapi_nr_ul_tti_request_t is very big, let's copy only what is necessary */ /* the structure nfapi_nr_ul_tti_request_t is very big, let's copy only what is necessary */
static void copy_ul_tti_req(nfapi_nr_ul_tti_request_t *to, nfapi_nr_ul_tti_request_t *from) static void copy_ul_tti_req(nfapi_nr_ul_tti_request_t *to, nfapi_nr_ul_tti_request_t *from)
{ {
...@@ -215,8 +166,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ ...@@ -215,8 +166,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_SCHED_LOCK(&gNB->sched_lock); NR_SCHED_LOCK(&gNB->sched_lock);
int slots_frame = gNB->frame_structure.numb_slots_frame;
clear_beam_information(&gNB->beam_info, frame, slot, *scc->ssbSubcarrierSpacing); clear_beam_information(&gNB->beam_info, frame, slot, slots_frame);
gNB->frame = frame; gNB->frame = frame;
start_meas(&gNB->eNB_scheduler); start_meas(&gNB->eNB_scheduler);
...@@ -240,9 +191,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ ...@@ -240,9 +191,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
for (int i = 0; i < num_beams; i++) for (int i = 0; i < num_beams; i++)
memset(cc[CC_id].vrb_map[i], 0, sizeof(uint16_t) * MAX_BWP_SIZE); memset(cc[CC_id].vrb_map[i], 0, sizeof(uint16_t) * MAX_BWP_SIZE);
// clear last scheduled slot's content (only)! // clear last scheduled slot's content (only)!
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int size = gNB->vrb_map_UL_size; const int size = gNB->vrb_map_UL_size;
const int prev_slot = frame * num_slots + slot + size - 1; const int prev_slot = frame * slots_frame + slot + size - 1;
for (int i = 0; i < num_beams; i++) { for (int i = 0; i < num_beams; i++) {
uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL[i]; uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL[i];
memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE); memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE);
...@@ -277,14 +227,14 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ ...@@ -277,14 +227,14 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
slot, because otherwise we would allocate the current slot in slot, because otherwise we would allocate the current slot in
UL_tti_req_ahead), but be aware that, e.g., K2 is allowed to be larger UL_tti_req_ahead), but be aware that, e.g., K2 is allowed to be larger
(schedule_nr_prach will assert if resources are not free). */ (schedule_nr_prach will assert if resources are not free). */
const sub_frame_t n_slots_ahead = nr_slots_per_frame[*scc->ssbSubcarrierSpacing] - 1 + get_NTN_Koffset(scc); const sub_frame_t n_slots_ahead = slots_frame - 1 + get_NTN_Koffset(scc);
const frame_t f = (frame + (slot + n_slots_ahead) / nr_slots_per_frame[*scc->ssbSubcarrierSpacing]) % 1024; const frame_t f = (frame + (slot + n_slots_ahead) / slots_frame) % 1024;
const sub_frame_t s = (slot + n_slots_ahead) % nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const sub_frame_t s = (slot + n_slots_ahead) % slots_frame;
schedule_nr_prach(module_idP, f, s); schedule_nr_prach(module_idP, f, s);
} }
// Schedule CSI-RS transmission // Schedule CSI-RS transmission
nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing], &sched_info->DL_req); nr_csirs_scheduling(module_idP, frame, slot, &sched_info->DL_req);
// Schedule CSI measurement reporting // Schedule CSI measurement reporting
nr_csi_meas_reporting(module_idP, frame, slot); nr_csi_meas_reporting(module_idP, frame, slot);
...@@ -313,7 +263,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ ...@@ -313,7 +263,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
* is more than 1 CC supported? * is more than 1 CC supported?
*/ */
AssertFatal(MAX_NUM_CCs == 1, "only 1 CC supported\n"); AssertFatal(MAX_NUM_CCs == 1, "only 1 CC supported\n");
const int current_index = ul_buffer_index(frame, slot, *scc->ssbSubcarrierSpacing, gNB->UL_tti_req_ahead_size); const int current_index = ul_buffer_index(frame, slot, slots_frame, gNB->UL_tti_req_ahead_size);
copy_ul_tti_req(&sched_info->UL_tti_req, &gNB->UL_tti_req_ahead[0][current_index]); copy_ul_tti_req(&sched_info->UL_tti_req, &gNB->UL_tti_req_ahead[0][current_index]);
stop_meas(&gNB->eNB_scheduler); stop_meas(&gNB->eNB_scheduler);
......
This diff is collapsed.
...@@ -172,6 +172,7 @@ typedef struct nr_mac_config_t { ...@@ -172,6 +172,7 @@ typedef struct nr_mac_config_t {
/// beamforming weight matrix size /// beamforming weight matrix size
int nb_bfw[2]; int nb_bfw[2];
int32_t *bw_list; int32_t *bw_list;
int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
} nr_mac_config_t; } nr_mac_config_t;
typedef struct NR_preamble_ue { typedef struct NR_preamble_ue {
...@@ -675,6 +676,10 @@ typedef struct { ...@@ -675,6 +676,10 @@ typedef struct {
/// per-LC configuration /// per-LC configuration
seq_arr_t lc_config; seq_arr_t lc_config;
// pdcch closed loop adjust for PDCCH aggregation level, range <0, 1>
// 0 - good channel, 1 - bad channel
float pdcch_cl_adjust;
} NR_UE_sched_ctrl_t; } NR_UE_sched_ctrl_t;
typedef struct { typedef struct {
......
...@@ -794,7 +794,7 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, ...@@ -794,7 +794,7 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
int slots_per_frame = 20; //30 kHZ subcarrier spacing int slots_per_frame = 20; //30 kHZ subcarrier spacing
int slot_ahead = 2; // TODO: Make this dynamic int slot_ahead = 2; // TODO: Make this dynamic
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, (slot + slot_ahead) % slots_per_frame, mac->frame_type) if (is_ul_slot((slot + slot_ahead) % slots_per_frame, &mac->frame_structure)
&& mac->ra.ra_state != nrRA_SUCCEEDED) { && mac->ra.ra_state != nrRA_SUCCEEDED) {
// If we filled dl_info AFTER we got the slot indication, we want to check if we should fill tx_req: // If we filled dl_info AFTER we got the slot indication, we want to check if we should fill tx_req:
nr_uplink_indication_t ul_info = {.slot = (slot + slot_ahead) % slots_per_frame, nr_uplink_indication_t ul_info = {.slot = (slot + slot_ahead) % slots_per_frame,
...@@ -1203,7 +1203,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info) ...@@ -1203,7 +1203,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info)
LOG_T(NR_MAC, "Not calling scheduler mac->ra.ra_state = %d\n", mac->ra.ra_state); LOG_T(NR_MAC, "Not calling scheduler mac->ra.ra_state = %d\n", mac->ra.ra_state);
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, ul_info->slot, mac->frame_type)) if (is_ul_slot(ul_info->slot, &mac->frame_structure))
nr_ue_ul_scheduler(mac, ul_info); nr_ue_ul_scheduler(mac, ul_info);
ret = pthread_mutex_unlock(&mac->if_mutex); ret = pthread_mutex_unlock(&mac->if_mutex);
AssertFatal(!ret, "mutex failed %d\n", ret); AssertFatal(!ret, "mutex failed %d\n", ret);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -12,3 +12,5 @@ position0 = { ...@@ -12,3 +12,5 @@ position0 = {
y = 0.0; y = 0.0;
z = 6377900.0; z = 6377900.0;
} }
@include "channelmod_rfsimu_LEO_satellite.conf"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment