Compare commits

...

11 Commits

Author SHA1 Message Date
Nuno Domingues
4aeee8fbc1 Merge branch '2_Step_RA_fixes' into 'develop'
Improvements for 2-Step RA

See merge request oai/openairinterface5g!4106
2026-07-02 06:32:32 +00:00
Robert Schmidt
c4125d1c74 Fix license in files from PR #211
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-06-29 16:27:21 +02:00
ndomingues
26956bf8e1 Create CI test for 2-Step RA
Signed-off-by: Nuno Domingues <ndomingues@allbesmart.pt>
2026-05-20 10:25:01 +01:00
ndomingues
3a8e3b9408 Demote sharedROs Assert Fatal to LOG_E to get RA 2-Step working
sharedROs feature to be implemented in the future

Signed-off-by: Nuno Domingues <ndomingues@allbesmart.pt>
2026-05-20 10:24:49 +01:00
ndomingues
c9461ac4d4 Improve LOGs to better handle RA 2-Step
Signed-off-by: Nuno Domingues <ndomingues@allbesmart.pt>
2026-05-20 10:24:40 +01:00
ndomingues
d95d911e96 For RA 2-Step consider RA failed if MsgA-PUSCH not detected
Signed-off-by: Nuno Domingues <ndomingues@allbesmart.pt>
2026-05-20 10:24:26 +01:00
ndomingues
97ac8a5cd1 Implementation of the response window timer for 2-Step RA
Signed-off-by: Nuno Domingues <ndomingues@allbesmart.pt>
2026-05-20 10:24:16 +01:00
ndomingues
778fb90f44 Update prach_ConfigurationIndex to get more reliable PRACH detection with USRPs
Signed-off-by: Nuno Domingues <ndomingues@allbesmart.pt>
2026-05-20 10:23:46 +01:00
ndomingues
80735e2b39 Schedule MsgA-PUSCH even if there are UEs connected
Signed-off-by: Nuno Domingues <ndomingues@allbesmart.pt>
2026-05-20 10:22:45 +01:00
ndomingues
ed53bd8f95 Increase RA frame buffer size for 2-step RA to avoid MsgA-PUSCH and ACK/NACK collision
Signed-off-by: Nuno Domingues <ndomingues@allbesmart.pt>
2026-05-20 10:22:26 +01:00
ndomingues
ea35109ba2 Improve find_ra_UE function to return UE identified by RA-RNTI required for MsgA-PUSCH
Signed-off-by: Nuno Domingues <ndomingues@allbesmart.pt>
2026-05-20 10:22:05 +01:00
12 changed files with 598 additions and 60 deletions

View File

@@ -0,0 +1,271 @@
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) });
nr_cellid = 12345678L;
////////// Physical parameters:
do_CSIRS = 1;
do_SRS = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641280;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640008;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 148;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 10;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#one (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# 0=sl1, 1=sl2, 2=sl4, 3=sl8, 4=sl10, 5=sl20, 6=sl40, 7=sl80, 8=sl160, 9=sl320
msgB_ResponseWindow_r16 = 5;
msgA_RSRP_Threshold_r16 = 19;
msgA_CB_PreamblesPerSSB_PerSharedRO_r16 = 1;
msgA_MCS_r16 = 2;
nrofSlotsMsgA_PUSCH_r16 = 1;
# 0=one, 1=two, 2=three, 3=six
nrofMsgA_PO_PerSlot_r16 = 0;
msgA_PUSCH_TimeDomainOffset_r16 = 8;
startSymbolAndLengthMsgA_PO_r16 = 38;
mappingTypeMsgA_PUSCH_r16 = 0;
guardBandMsgA_PUSCH_r16 = 0;
frequencyStartMsgA_PUSCH_r16 = 0;
nrofPRBs_PerMsgA_PO_r16 = 8;
# 0=one, 1=two, 2=four, 3=eight
nrofMsgA_PO_FDM_r16 = 0;
msgA_PUSCH_NrofPorts_r16 = 1;
nrofDMRS_Sequences_r16 = 1;
# 0=enabled, 1=disabled
msgA_TransformPrecoder_r16 = 1;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "192.168.71.132"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/24";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200;
}
);
L1s = (
{
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 100;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 12;
att_rx = 12;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
clock_src = "internal";
}
);
rfsimulator :
{
serveraddr = "server";
serverport = 4043;
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
ngap_log_level ="debug";
f1ap_log_level ="debug";
};
e2_agent = {
near_ric_ip_addr = "127.0.0.1";
#sm_dir = "/path/where/the/SMs/are/located/"
sm_dir = "/usr/local/lib/flexric/"
};

View File

@@ -0,0 +1,85 @@
<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->
<testCaseList>
<htmlTabRef>monolithic_2step_ra_gnb_rfsim</htmlTabRef>
<htmlTabName>Monolithic 2-Step RA gNB rfsim</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<testCase>
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<node>localhost</node>
<images>oai-gnb-asan oai-nr-ue-asan</images>
</testCase>
<testCase>
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<node>localhost</node>
</testCase>
<testCase>
<class>Deploy_Object</class>
<desc>Deploy OAI gNB</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/monolithic_2step_ra_gnb_rfsim</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
</testCase>
<testCase>
<class>Deploy_Object</class>
<desc>Deploy OAI NR-UE</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/monolithic_2step_ra_gnb_rfsim</yaml_path>
<services>oai-gnb oai-nr-ue</services>
</testCase>
<testCase>
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<node>localhost</node>
</testCase>
<testCase>
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<node>localhost</node>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i0.2</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
<testCase>
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<node>localhost</node>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i0.2</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
<testCase>
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 5G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/monolithic_2step_ra_gnb_rfsim</yaml_path>
<analysis>
<services>oai-gnb=RetxCheck=10,0,0,0 oai-gnb=EndsWithBye oai-nr-ue</services>
</analysis>
</testCase>
<testCase>
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<node>localhost</node>
<images>oai-gnb-asan oai-nr-ue-asan</images>
</testCase>
</testCaseList>

View File

@@ -0,0 +1,162 @@
# SPDX-License-Identifier: MIT
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
environment:
- TZ=Europe/Paris
- MYSQL_DATABASE=oai_db
- MYSQL_USER=test
- MYSQL_PASSWORD=test
- MYSQL_ROOT_PASSWORD=linux
healthcheck:
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
start_period: 10s
start_interval: 500ms
interval: 10s
timeout: 5s
retries: 30
networks:
public_net:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
environment:
- TZ=Europe/paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-amf/etc/config.yaml
depends_on:
- mysql
networks:
public_net:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-smf/etc/config.yaml
depends_on:
- oai-amf
networks:
public_net:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
init: true
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-upf/etc/config.yaml
depends_on:
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
cap_drop:
- ALL
privileged: true
networks:
public_net:
ipv4_address: 192.168.71.134
interface_name: eth0
traffic_net:
ipv4_address: 192.168.72.134
interface_name: eth1
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
depends_on:
- oai-upf
networks:
traffic_net:
ipv4_address: 192.168.72.135
healthcheck:
test: /bin/bash -c "ping -c 2 192.168.72.134"
start_period: 10s
start_interval: 500ms
interval: 10s
timeout: 5s
retries: 5
oai-gnb:
image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop}
container_name: rfsim5g-oai-gnb
cap_drop:
- ALL
environment:
USE_ADDITIONAL_OPTIONS: --rfsim --log_config.global_log_options level,nocolor,time
ASAN_OPTIONS: detect_leaks=0
networks:
public_net:
ipv4_address: 192.168.71.140
volumes:
- ../../conf_files/gnb.sa.band78.106prb.usrpb210.RA_2-Step.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
start_period: 10s
start_interval: 500ms
interval: 10s
timeout: 5s
retries: 5
oai-nr-ue:
image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop}
container_name: rfsim5g-oai-nr-ue
cap_drop:
- ALL
cap_add:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
USE_ADDITIONAL_OPTIONS: --rfsim
--rfsimulator.[0].serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
-C 3619200000 -r 106 --numerology 1 --ssb 516 --band 78
ASAN_OPTIONS: detect_leaks=0
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
depends_on:
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.71.150
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
start_period: 10s
start_interval: 500ms
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
driver: bridge
name: rfsim5g-oai-public-net
ipam:
config:
- subnet: 192.168.71.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-public"
traffic_net:
driver: bridge
name: rfsim5g-oai-traffic-net
ipam:
config:
- subnet: 192.168.72.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-traffic"

View File

@@ -1,23 +1,7 @@
/*
* 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
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include "common/config/config_userapi.h"
#include "common/utils/system.h"
#include "nr-oru.h"

View File

@@ -1,23 +1,7 @@
/*
* 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
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#ifndef __NR_ORU_H__
#define __NR_ORU_H__
#include "openair1/PHY/defs_RU.h"

View File

@@ -287,7 +287,8 @@ static void config_preamble_index(NR_UE_MAC_INST_t *mac)
// The field is mandatory present if the 2-step random access type occasions are shared with 4-step random access type,
// otherwise the field is not present
bool sharedROs = twostep->msgA_CB_PreamblesPerSSB_PerSharedRO_r16 != NULL;
AssertFatal(sharedROs == false, "Shared ROs between 2- and 4-step RA not supported\n");
if (!sharedROs)
LOG_E(NR_MAC, "Shared ROs between 2- and 4-step RA not supported\n");
// For Type-2 random access procedure with separate configuration of PRACH occasions with Type-1 random access procedure
// configuration by msgA-SSB-PerRACH-OccasionAndCB-PreamblesPerSSB when provided;
@@ -1157,12 +1158,15 @@ void nr_ra_contention_resolution_failed(NR_UE_MAC_INST_t *mac)
void nr_rar_not_successful(NR_UE_MAC_INST_t *mac)
{
LOG_W(MAC, "[UE %d] RAR reception failed\n", mac->ue_id);
RA_config_t *ra = &mac->ra;
LOG_W(MAC, "[UE %d] Response window timer expired, %s reception failed\n", mac->ue_id, ra->ra_type == RA_2_STEP ? "MsgB" : "RAR");
NR_PRACH_RESOURCES_t *prach_resources = &ra->prach_resources;
prach_resources->preamble_tx_counter++;
bool ra_completed = false;
if (prach_resources->preamble_tx_counter == ra->preambleTransMax + 1) {
if (ra->ra_type == RA_2_STEP) {
AssertFatal(false, "Fallback to 4-Step RA not implemented\n");
}
// if the Random Access Preamble is transmitted on the SpCell
// TODO to be verified, this means SA if I'm not mistaken
if (IS_SA_MODE(get_softmodem_params())) {

View File

@@ -1677,6 +1677,23 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t
ra->t_crnti = 0;
mac->crnti = 0;
ra->ra_rnti = 0;
// start MsgB response window timer
int next_slot = (slotP + 1) % n_slots_frame;
int next_frame = (frameP + (next_slot < slotP)) % MAX_FRAME_NUMBER;
int add_slots = 1;
NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[mac->current_DL_BWP->bwp_id];
const NR_SearchSpace_t *ra_SS = get_common_search_space(mac, pdcch_config->ra_SS_id);
while (!is_dl_slot(next_slot, &mac->frame_structure)
|| !is_ss_monitor_occasion(next_frame, next_slot, n_slots_frame, ra_SS)) {
int temp_slot = (next_slot + 1) % n_slots_frame;
next_frame = (next_frame + (temp_slot < next_slot)) % MAX_FRAME_NUMBER;
next_slot = temp_slot;
add_slots++;
}
add_slots += GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mac->current_DL_BWP->scs);
nr_timer_setup(&ra->response_window_timer, ra->response_window_setup_time + add_slots, 1);
nr_timer_start(&ra->response_window_timer);
} else {
AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type);
}

View File

@@ -941,7 +941,19 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
const int n = get_slots_per_frame_from_scs(*scc->ssbSubcarrierSpacing);
const int size = n << (int)ceil(log2((NTN_gNB_Koffset + 13) / n + 1)); // 13 is upper limit for max_fb_time
int size = n << (int)ceil(log2((NTN_gNB_Koffset + 13) / n + 1)); // 13 is upper limit for max_fb_time
// If the RA is configured as 2-step, the size must be increased to accommodate more frames. This allows MsgA-PUSCH and the
// ACK/NACK to be scheduled within the same slot, as they reside in different frames. Consequently, multiple MsgA-PUSCH
// transmissions can be scheduled without overriding the ACK/NACK.
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1
&& scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16
->msgA_PUSCH_ResourceGroupA_r16->msgA_PUSCH_TimeDomainOffset_r16) {
NR_MsgA_ConfigCommon_r16_t *msgacc = scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup;
int msgA_PUSCH_TimeDomainOffset = msgacc->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->msgA_PUSCH_TimeDomainOffset_r16;
size *= (n + msgA_PUSCH_TimeDomainOffset + (n - 1)) / n;
}
nrmac->vrb_map_UL_size = size;
int num_beams = 1;

View File

@@ -476,7 +476,6 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
}
}
if (initialUplinkBWP->ext1 && initialUplinkBWP->ext1->msgA_ConfigCommon_r16) {
if (gNB->UE_info.connected_ue_list[0] == NULL)
schedule_nr_MsgA_pusch(scc->uplinkConfigCommon,
gNB,
module_idP,

View File

@@ -2607,6 +2607,10 @@ NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP)
NR_UE_info_t *find_ra_UE(NR_UEs_t *UEs, rnti_t rntiP)
{
UE_iterator(UEs->access_ue_list, UE) {
if (UE->ra->ra_type == RA_2_STEP && UE->ra->RA_rnti == rntiP) {
LOG_D(NR_MAC, "Search and found RA 2-Step RA_rnti: %04x\n", rntiP);
return UE;
}
if (UE->rnti == rntiP) {
LOG_D(NR_MAC,"Search and found rnti: %04x\n", rntiP);
return UE;

View File

@@ -702,6 +702,18 @@ static void handle_nr_ul_harq(gNB_MAC_INST *nrmac, NR_UE_info_t *UE, rnti_t rnti
static void handle_msg3_failed_rx(gNB_MAC_INST *mac, NR_RA_t *ra, rnti_t rnti, int harq_round_max)
{
// for CFRA (NSA) do not schedule retransmission of msg3
// For RA 2-Step consider RA failed if MsgA-PUSCH not detected
if (ra->cfra || ra->ra_type == RA_2_STEP) {
LOG_W(NR_MAC,
"UE %04x RA failed at state %s (%s reception failed)\n",
rnti,
nrra_text[ra->ra_state],
ra->ra_type == RA_2_STEP ? "MsgA-PUSCH" : "NSA Msg3");
nr_release_ra_UE(mac, rnti);
return;
}
if (ra->msg3_round >= harq_round_max - 1) {
LOG_W(NR_MAC, "UE %04x RA failed at state %s (Reached msg3 max harq rounds)\n", rnti, nrra_text[ra->ra_state]);
nr_release_ra_UE(mac, rnti);
@@ -729,7 +741,7 @@ static void nr_rx_ra_sdu(const module_id_t mod_id,
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
NR_UE_info_t *UE = find_ra_UE(&mac->UE_info, rnti);
if (!UE) {
LOG_E(NR_MAC, "UL SDU discarded. Couldn't finde UE with RNTI %04x \n", rnti);
LOG_D(NR_MAC, "UL SDU discarded. Couldn't find UE with RNTI %04x \n", rnti);
return;
}
@@ -773,16 +785,19 @@ static void nr_rx_ra_sdu(const module_id_t mod_id,
if (cfra) // no Msg3 on CFRA, no problem
return;
if (ra->ra_state != nrRA_WAIT_Msg3)
if (ra->ra_type == RA_4_STEP && ra->ra_state != nrRA_WAIT_Msg3)
return;
if((frame!=ra->Msg3_frame) || (slot!=ra->Msg3_slot))
if (ra->ra_type == RA_2_STEP && ra->ra_state != nrRA_WAIT_MsgA_PUSCH)
return;
if (ra->ra_type == RA_4_STEP && ((frame != ra->Msg3_frame) || (slot != ra->Msg3_slot)))
return;
if (ul_cqi != 0xff)
ra->msg3_TPC = nr_mac_get_tpc(&UE->UE_sched_ctrl.pusch_pc);
handle_msg3_failed_rx(mac, ra, rnti, mac->ul_bler.harq_round_max);
handle_msg3_failed_rx(mac, ra, UE->rnti, mac->ul_bler.harq_round_max);
return;
}
@@ -801,15 +816,15 @@ static void nr_rx_ra_sdu(const module_id_t mod_id,
if (no_sig) {
LOG_W(NR_MAC, "MSG3 ULSCH with no signal\n");
LOG_W(NR_MAC, "%s ULSCH with no signal\n", ra->ra_type == RA_2_STEP ? "MsgA-PUSCH" : "MSG3");
if (!cfra)
handle_msg3_failed_rx(mac, ra, rnti, mac->ul_bler.harq_round_max);
handle_msg3_failed_rx(mac, ra, UE->rnti, mac->ul_bler.harq_round_max);
return;
}
if (!cfra && ra->ra_type == RA_2_STEP) {
// random access pusch with RA-RNTI
if (ra->RA_rnti != rnti) {
LOG_E(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->RA_rnti, rnti);
LOG_E(NR_MAC, "expected RA_RNTI %04x to match current RNTI %04x\n", ra->RA_rnti, rnti);
return;
}
}
@@ -817,7 +832,7 @@ static void nr_rx_ra_sdu(const module_id_t mod_id,
// re-initialize ta update variables after RA procedure completion
UE->UE_sched_ctrl.ta_frame = (frame + 100) % MAX_FRAME_NUMBER;
LOG_A(NR_MAC, "%4d.%2d PUSCH with TC_RNTI 0x%04x received correctly\n", frame, slot, rnti);
LOG_A(NR_MAC, "%4d.%2d PUSCH with %s 0x%04x received correctly\n", frame, slot, ra->ra_type == RA_2_STEP ? "RA_RNTI" : "TC_RNTI", rnti);
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
DevAssert(harq_pid >= 0 && harq_pid < 8);
@@ -884,9 +899,10 @@ static void nr_rx_ra_sdu(const module_id_t mod_id,
nr_process_mac_pdu(mod_id, UE, frame, slot, sdu, sdu_len, harq_pid);
LOG_I(NR_MAC,
"Activating scheduling %s for TC_RNTI 0x%04x (state %s)\n",
"Activating scheduling %s for %s 0x%04x (state %s)\n",
ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4",
UE->rnti,
ra->ra_type == RA_2_STEP ? "MsgB_rnti" : "TC_RNTI",
ra->ra_type == RA_2_STEP ? UE->ra->MsgB_rnti : UE->rnti,
nrra_text[ra->ra_state]);
ra->ra_state = ra->ra_type == RA_2_STEP ? nrRA_MsgB : nrRA_Msg4;
LOG_D(NR_MAC, "TC_RNTI 0x%04x next RA state %s\n", UE->rnti, nrra_text[ra->ra_state]);

View File

@@ -70,7 +70,7 @@ gNBs =
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
prach_ConfigurationIndex = 148;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
@@ -106,7 +106,7 @@ gNBs =
p0_NominalWithGrant =-90;
# 0=sl1, 1=sl2, 2=sl4, 3=sl8, 4=sl10, 5=sl20, 6=sl40, 7=sl80, 8=sl160, 9=sl320
msgB_ResponseWindow_r16 = 2;
msgB_ResponseWindow_r16 = 6;
msgA_RSRP_Threshold_r16 = 19;
msgA_CB_PreamblesPerSSB_PerSharedRO_r16 = 1;