Merge remote-tracking branch 'origin/CI-ho-attenuator-N2' into integration_2025_w43 (!3708)
Add monolithic N2 handover test pipeline with B210 and Quectel The goal of this MR is to provide an automated end-to-end N2 HO validation with real RF (B210) and Quectel UE. During the testing phase a post-HO assertion failure due to uninitialized selected_plmn_identity was found: this was also fixed. CI: Add monolithic N2 handover test pipeline (B210 + Quectel) - New XML pipeline for N2 HO testing - Docker Compose for two monolithic gNBs (gNB1/gNB2) - Handover sequence: gNB1 → gNB2 → gNB1 with 5s controlled attenuation (RC4DAT). - Channel mapping: ch1-2 gNB1, ch3-4 gNB2 - Telnet server enabled for CI commands - Clean-up/reset of attenuator state included NGAP - fix PLMN/cell location for Initial UE and Uplink NAS - Prevents assertion in ngap_gNB_nas_uplink() due to uninitialized selected_plmn_identity - Initial UE Message: pass UE-selected PLMN and NR cell ID from RRC to NGAP - Uplink NAS Transport: use PLMN, TAC, and cell ID from the message - Build NR CGI as gNB ID + cell ID - Store UE-selected PLMN only in RRC UE context (for later NAS); stop storing PLMN in NGAP UE context. - PLMN validation when processing handover requests from the source gNB: when PLMN validation fails, the target gNB now properly sends NGAP_HANDOVER_FAILURE - Store serving PLMN for later use in UE context
This commit is contained in:
@@ -0,0 +1,237 @@
|
|||||||
|
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 = 03; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
|
||||||
|
|
||||||
|
// Include neighbour configuration for N2 handover
|
||||||
|
@include "neighbour-config-ho.conf"
|
||||||
|
|
||||||
|
nr_cellid = 12345678L;
|
||||||
|
|
||||||
|
////////// Physical parameters:
|
||||||
|
|
||||||
|
|
||||||
|
servingCellConfigCommon = (
|
||||||
|
{
|
||||||
|
#spCellConfigCommon
|
||||||
|
|
||||||
|
physCellId = 0;
|
||||||
|
|
||||||
|
# downlinkConfigCommon
|
||||||
|
#frequencyInfoDL
|
||||||
|
# this is 3610.56 MHz
|
||||||
|
absoluteFrequencySSB = 679104;
|
||||||
|
dl_frequencyBand = 77;
|
||||||
|
# this is 3599.94 MHz
|
||||||
|
dl_absoluteFrequencyPointA = 678388;
|
||||||
|
#scs-SpecificCarrierList
|
||||||
|
dl_offstToCarrier = 0;
|
||||||
|
# subcarrierSpacing
|
||||||
|
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||||
|
dl_subcarrierSpacing = 1;
|
||||||
|
dl_carrierBandwidth = 51;
|
||||||
|
#initialDownlinkBWP
|
||||||
|
#genericParameters
|
||||||
|
# this is RBstart=27,L=48 (275*(L-1))+RBstart
|
||||||
|
initialDLBWPlocationAndBandwidth = 13750;
|
||||||
|
# subcarrierSpacing
|
||||||
|
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||||
|
initialDLBWPsubcarrierSpacing = 1;
|
||||||
|
#pdcch-ConfigCommon
|
||||||
|
initialDLBWPcontrolResourceSetZero = 12;
|
||||||
|
initialDLBWPsearchSpaceZero = 0;
|
||||||
|
|
||||||
|
#uplinkConfigCommon
|
||||||
|
#frequencyInfoUL
|
||||||
|
ul_frequencyBand = 77;
|
||||||
|
#scs-SpecificCarrierList
|
||||||
|
ul_offstToCarrier = 0;
|
||||||
|
# subcarrierSpacing
|
||||||
|
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||||
|
ul_subcarrierSpacing = 1;
|
||||||
|
ul_carrierBandwidth = 51;
|
||||||
|
pMax = 20;
|
||||||
|
#initialUplinkBWP
|
||||||
|
#genericParameters
|
||||||
|
initialULBWPlocationAndBandwidth = 13750;
|
||||||
|
# subcarrierSpacing
|
||||||
|
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||||
|
initialULBWPsubcarrierSpacing = 1;
|
||||||
|
#rach-ConfigCommon
|
||||||
|
#rach-ConfigGeneric
|
||||||
|
prach_ConfigurationIndex = 98;
|
||||||
|
#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 = 6;
|
||||||
|
#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;
|
||||||
|
|
||||||
|
# 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 = "172.21.6.109"; });
|
||||||
|
|
||||||
|
|
||||||
|
NETWORK_INTERFACES :
|
||||||
|
{
|
||||||
|
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.19.98";
|
||||||
|
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.19.98";
|
||||||
|
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
MACRLCs = (
|
||||||
|
{
|
||||||
|
num_cc = 1;
|
||||||
|
tr_s_preference = "local_L1";
|
||||||
|
tr_n_preference = "local_RRC";
|
||||||
|
pusch_TargetSNRx10 = 200;
|
||||||
|
pucch_TargetSNRx10 = 200;
|
||||||
|
ul_prbblack_SNR_threshold = 10;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
L1s = (
|
||||||
|
{
|
||||||
|
num_cc = 1;
|
||||||
|
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 = 0;
|
||||||
|
att_rx = 0;
|
||||||
|
bands = [77];
|
||||||
|
max_pdschReferenceSignalPower = -27;
|
||||||
|
max_rxgain = 114;
|
||||||
|
eNB_instances = [0];
|
||||||
|
clock_src = "external";
|
||||||
|
time_src = "external";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,230 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
-->
|
||||||
|
<testCaseList>
|
||||||
|
<htmlTabRef>TEST-MONO-N2-HO-B210</htmlTabRef>
|
||||||
|
<htmlTabName>Monolithic N2 Handover 20 MHz TDD SA</htmlTabName>
|
||||||
|
<htmlTabIcon>tasks</htmlTabIcon>
|
||||||
|
<TestCaseRequestedList>
|
||||||
|
000001
|
||||||
|
000002
|
||||||
|
000023
|
||||||
|
000003
|
||||||
|
000004
|
||||||
|
000005
|
||||||
|
000006
|
||||||
|
000007
|
||||||
|
000008
|
||||||
|
000009
|
||||||
|
000010
|
||||||
|
000011
|
||||||
|
000012
|
||||||
|
000013
|
||||||
|
000014
|
||||||
|
000015
|
||||||
|
000017
|
||||||
|
000018
|
||||||
|
000019
|
||||||
|
000016
|
||||||
|
000020
|
||||||
|
000021
|
||||||
|
000022
|
||||||
|
</TestCaseRequestedList>
|
||||||
|
<TestCaseExclusionList></TestCaseExclusionList>
|
||||||
|
|
||||||
|
<testCase id="000001">
|
||||||
|
<class>DeployCoreNetwork</class>
|
||||||
|
<desc>Initialize 5G Core</desc>
|
||||||
|
<cn_id>oc-cn5g-00103-ho</cn_id>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000002">
|
||||||
|
<class>Pull_Local_Registry</class>
|
||||||
|
<desc>Pull Images from Local Registry</desc>
|
||||||
|
<images>oai-gnb</images>
|
||||||
|
<node>groot</node>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000023">
|
||||||
|
<class>Pull_Local_Registry</class>
|
||||||
|
<desc>Pull Images from Local Registry</desc>
|
||||||
|
<images>oai-gnb</images>
|
||||||
|
<node>rocket</node>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000003">
|
||||||
|
<class>Create_Workspace</class>
|
||||||
|
<desc>Create new Workspace for groot</desc>
|
||||||
|
<node>groot</node>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000005">
|
||||||
|
<class>Create_Workspace</class>
|
||||||
|
<desc>Create new Workspace on rocket</desc>
|
||||||
|
<node>rocket</node>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000004">
|
||||||
|
<class>Custom_Command</class>
|
||||||
|
<desc>Set initial attenuation on target gNB</desc>
|
||||||
|
<node>rocket</node>
|
||||||
|
<command>python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1,2 0 -s 3,4 15</command>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000005">
|
||||||
|
<class>Deploy_Object</class>
|
||||||
|
<desc>Deploy Monolithic gNB-PCI0 (TDD/Band77/20MHz/B210) in a container</desc>
|
||||||
|
<yaml_path>ci-scripts/yaml_files/5g_sa_n2_ho_b210</yaml_path>
|
||||||
|
<node>groot</node>
|
||||||
|
<services>oai-gnb-pci0</services>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000006">
|
||||||
|
<class>Deploy_Object</class>
|
||||||
|
<desc>Deploy Monolithic gNB-PCI1 (TDD/Band77/20MHz/B210) in a container</desc>
|
||||||
|
<yaml_path>ci-scripts/yaml_files/5g_sa_n2_ho_b210</yaml_path>
|
||||||
|
<node>rocket</node>
|
||||||
|
<services>oai-gnb-pci1</services>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000007">
|
||||||
|
<class>Attach_UE</class>
|
||||||
|
<desc>Attach Quectel</desc>
|
||||||
|
<id>raspix</id>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000008">
|
||||||
|
<class>Ping</class>
|
||||||
|
<desc>Ping: 100pings in 20sec</desc>
|
||||||
|
<id>raspix</id>
|
||||||
|
<svr_id>oc-cn5g-00103-ho</svr_id>
|
||||||
|
<ping_args>-c 100 -i 0.2</ping_args>
|
||||||
|
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000009">
|
||||||
|
<class>IdleSleep</class>
|
||||||
|
<desc>Sleep</desc>
|
||||||
|
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000010">
|
||||||
|
<class>Custom_Command</class>
|
||||||
|
<desc>Gradually attenuate gNB-PCI0 (ch1-2=15dB) and gNB-PCI1 (ch3-4=0dB) over 5s to trigger N2 Handover to gNB-PCI1</desc>
|
||||||
|
<node>rocket</node>
|
||||||
|
<command>python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 15 -r 3,4 0 -d 5</command>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000011">
|
||||||
|
<class>Ping</class>
|
||||||
|
<desc>Ping: 50pings in 10sec</desc>
|
||||||
|
<id>raspix</id>
|
||||||
|
<svr_id>oc-cn5g-00103-ho</svr_id>
|
||||||
|
<ping_args>-c 50 -i 0.2</ping_args>
|
||||||
|
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000012">
|
||||||
|
<class>Custom_Command</class>
|
||||||
|
<desc>UE connected to gNB-PCI1?</desc>
|
||||||
|
<node>rocket</node>
|
||||||
|
<command>echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3585"</command>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000013">
|
||||||
|
<class>Custom_Command</class>
|
||||||
|
<desc>Gradually attenuate gNB-PCI0 (ch1-2=0dB) and gNB-PCI1 (ch3-4=15dB) over 5s to trigger N2 Handover back to gNB-PCI0</desc>
|
||||||
|
<node>rocket</node>
|
||||||
|
<command>python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 15 -d 5</command>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000014">
|
||||||
|
<class>Ping</class>
|
||||||
|
<desc>Ping: 50pings in 10sec</desc>
|
||||||
|
<id>raspix</id>
|
||||||
|
<svr_id>oc-cn5g-00103-ho</svr_id>
|
||||||
|
<ping_args>-c 50 -i 0.2</ping_args>
|
||||||
|
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000015">
|
||||||
|
<class>Custom_Command</class>
|
||||||
|
<desc>UE connected to gNB-PCI0?</desc>
|
||||||
|
<node>groot</node>
|
||||||
|
<command>echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3584"</command>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000016">
|
||||||
|
<class>Custom_Command</class>
|
||||||
|
<always_exec>true</always_exec>
|
||||||
|
<desc>Reset all attenuators to 0dB</desc>
|
||||||
|
<node>rocket</node>
|
||||||
|
<command>python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1-4 0</command>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000017">
|
||||||
|
<class>Detach_UE</class>
|
||||||
|
<always_exec>true</always_exec>
|
||||||
|
<desc>Detach Quectel</desc>
|
||||||
|
<id>raspix</id>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000018">
|
||||||
|
<class>Undeploy_Object</class>
|
||||||
|
<always_exec>true</always_exec>
|
||||||
|
<desc>Undeploy Monolithic gNB-PCI0</desc>
|
||||||
|
<node>groot</node>
|
||||||
|
<yaml_path>ci-scripts/yaml_files/5g_sa_n2_ho_b210</yaml_path>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000019">
|
||||||
|
<class>Undeploy_Object</class>
|
||||||
|
<always_exec>true</always_exec>
|
||||||
|
<desc>Undeploy Monolithic gNB-PCI1</desc>
|
||||||
|
<node>rocket</node>
|
||||||
|
<yaml_path>ci-scripts/yaml_files/5g_sa_n2_ho_b210</yaml_path>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000020">
|
||||||
|
<class>Clean_Test_Server_Images</class>
|
||||||
|
<always_exec>true</always_exec>
|
||||||
|
<desc>Clean Test Images on Test Server</desc>
|
||||||
|
<node>groot</node>
|
||||||
|
<images>oai-gnb</images>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000021">
|
||||||
|
<class>Clean_Test_Server_Images</class>
|
||||||
|
<always_exec>true</always_exec>
|
||||||
|
<desc>Clean Test Images on Test Server</desc>
|
||||||
|
<node>rocket</node>
|
||||||
|
<images>oai-gnb</images>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000022">
|
||||||
|
<class>UndeployCoreNetwork</class>
|
||||||
|
<always_exec>true</always_exec>
|
||||||
|
<desc>Terminate 5G Core</desc>
|
||||||
|
<cn_id>oc-cn5g-00103-ho</cn_id>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
</testCaseList>
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
services:
|
||||||
|
oai-gnb-pci0:
|
||||||
|
image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
|
||||||
|
container_name: oai-gnb-pci0
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- SYS_NICE
|
||||||
|
- IPC_LOCK
|
||||||
|
ulimits:
|
||||||
|
core: -1 # for core dumps
|
||||||
|
environment:
|
||||||
|
USE_B2XX: 'yes'
|
||||||
|
USE_ADDITIONAL_OPTIONS: --RUs.[0].sdr_addrs serial=30AD30F
|
||||||
|
--telnetsrv --telnetsrv.shrmod ci
|
||||||
|
--log_config.global_log_options level,nocolor,utc_time,line_num,function
|
||||||
|
ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0
|
||||||
|
devices:
|
||||||
|
- /dev/bus/usb/:/dev/bus/usb/
|
||||||
|
volumes:
|
||||||
|
- ../../conf_files/neighbour-config-ho.conf:/opt/oai-gnb/etc/neighbour-config-ho.conf
|
||||||
|
- ../../conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf:/opt/oai-gnb/etc/gnb.conf
|
||||||
|
network_mode: "host"
|
||||||
|
healthcheck:
|
||||||
|
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
oai-gnb-pci1:
|
||||||
|
image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
|
||||||
|
container_name: oai-gnb-pci1
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- SYS_NICE
|
||||||
|
- IPC_LOCK
|
||||||
|
ulimits:
|
||||||
|
core: -1 # for core dumps
|
||||||
|
environment:
|
||||||
|
USE_B2XX: 'yes'
|
||||||
|
USE_ADDITIONAL_OPTIONS: --RUs.[0].sdr_addrs serial=31F8010
|
||||||
|
--gNBs.[0].nr_cellid 11111111
|
||||||
|
--gNBs.[0].gNB_ID 0xe01
|
||||||
|
--gNBs.[0].servingCellConfigCommon.[0].physCellId 1
|
||||||
|
--gNBs.[0].servingCellConfigCommon.[0].ssb_PositionsInBurst_Bitmap 2
|
||||||
|
--gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 172.21.19.99
|
||||||
|
--gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NGU 172.21.19.99
|
||||||
|
--telnetsrv --telnetsrv.shrmod ci
|
||||||
|
--log_config.global_log_options level,nocolor,utc_time,line_num,function
|
||||||
|
devices:
|
||||||
|
- /dev/bus/usb/:/dev/bus/usb/
|
||||||
|
volumes:
|
||||||
|
- ../../conf_files/neighbour-config-ho.conf:/opt/oai-gnb/etc/neighbour-config-ho.conf
|
||||||
|
- ../../conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf:/opt/oai-gnb/etc/gnb.conf
|
||||||
|
network_mode: "host"
|
||||||
|
healthcheck:
|
||||||
|
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
@@ -37,9 +37,7 @@ typedef struct nssai_s {
|
|||||||
|
|
||||||
// Globally Unique AMF Identifier
|
// Globally Unique AMF Identifier
|
||||||
typedef struct nr_guami_s {
|
typedef struct nr_guami_s {
|
||||||
uint16_t mcc;
|
plmn_id_t plmn;
|
||||||
uint16_t mnc;
|
|
||||||
uint8_t mnc_len;
|
|
||||||
uint8_t amf_region_id;
|
uint8_t amf_region_id;
|
||||||
uint16_t amf_set_id;
|
uint16_t amf_set_id;
|
||||||
uint8_t amf_pointer;
|
uint8_t amf_pointer;
|
||||||
|
|||||||
@@ -421,6 +421,8 @@ typedef struct ngap_nas_first_req_s {
|
|||||||
/* PLMN: Selected PLMN Identity (optional)
|
/* PLMN: Selected PLMN Identity (optional)
|
||||||
* User Location Information (mandatory) */
|
* User Location Information (mandatory) */
|
||||||
plmn_id_t plmn;
|
plmn_id_t plmn;
|
||||||
|
// NR Cell ID for NR CGI (mandatory)
|
||||||
|
uint32_t nr_cell_id;
|
||||||
// RRC Establishment Cause (mandatory)
|
// RRC Establishment Cause (mandatory)
|
||||||
ngap_rrc_establishment_cause_t establishment_cause;
|
ngap_rrc_establishment_cause_t establishment_cause;
|
||||||
// NAS-PDU (mandatory)
|
// NAS-PDU (mandatory)
|
||||||
@@ -434,6 +436,10 @@ typedef struct ngap_uplink_nas_s {
|
|||||||
uint32_t gNB_ue_ngap_id;
|
uint32_t gNB_ue_ngap_id;
|
||||||
/* NAS pdu */
|
/* NAS pdu */
|
||||||
byte_array_t nas_pdu;
|
byte_array_t nas_pdu;
|
||||||
|
/* UserLocationInformation (mandatory) */
|
||||||
|
plmn_id_t plmn; // CGI and TAI
|
||||||
|
uint32_t nr_cell_id; // CGI
|
||||||
|
uint32_t tac; // TAI
|
||||||
} ngap_uplink_nas_t;
|
} ngap_uplink_nas_t;
|
||||||
|
|
||||||
typedef struct target_cell_id_s {
|
typedef struct target_cell_id_s {
|
||||||
|
|||||||
@@ -38,13 +38,11 @@ ue_id_e2sm_t fill_e2sm_gnb_ue_id_data(const gNB_RRC_UE_t *rrc_ue_context, __attr
|
|||||||
ue_id.gnb.amf_ue_ngap_id = auni < (1LL << 40) ? auni : 0;
|
ue_id.gnb.amf_ue_ngap_id = auni < (1LL << 40) ? auni : 0;
|
||||||
|
|
||||||
// Mandatory
|
// Mandatory
|
||||||
//GUAMI 6.2.3.17
|
//GUAMI 6.2.3.17
|
||||||
ue_id.gnb.guami.plmn_id = (e2sm_plmn_t) {
|
ue_id.gnb.guami.plmn_id = (e2sm_plmn_t){.mcc = rrc_ue_context->ue_guami.plmn.mcc,
|
||||||
.mcc = rrc_ue_context->ue_guami.mcc,
|
.mnc = rrc_ue_context->ue_guami.plmn.mnc,
|
||||||
.mnc = rrc_ue_context->ue_guami.mnc,
|
.mnc_digit_len = rrc_ue_context->ue_guami.plmn.mnc_digit_length};
|
||||||
.mnc_digit_len = rrc_ue_context->ue_guami.mnc_len
|
|
||||||
};
|
|
||||||
|
|
||||||
ue_id.gnb.guami.amf_region_id = rrc_ue_context->ue_guami.amf_region_id;
|
ue_id.gnb.guami.amf_region_id = rrc_ue_context->ue_guami.amf_region_id;
|
||||||
ue_id.gnb.guami.amf_set_id = rrc_ue_context->ue_guami.amf_set_id;
|
ue_id.gnb.guami.amf_set_id = rrc_ue_context->ue_guami.amf_set_id;
|
||||||
ue_id.gnb.guami.amf_ptr = rrc_ue_context->ue_guami.amf_pointer;
|
ue_id.gnb.guami.amf_ptr = rrc_ue_context->ue_guami.amf_pointer;
|
||||||
|
|||||||
@@ -209,6 +209,8 @@ typedef struct gNB_RRC_UE_s {
|
|||||||
uint64_t amf_ue_ngap_id;
|
uint64_t amf_ue_ngap_id;
|
||||||
// Globally Unique AMF Identifier
|
// Globally Unique AMF Identifier
|
||||||
nr_guami_t ue_guami;
|
nr_guami_t ue_guami;
|
||||||
|
// Serving PLMN of the UE
|
||||||
|
plmn_id_t serving_plmn;
|
||||||
|
|
||||||
ngap_security_capabilities_t security_capabilities;
|
ngap_security_capabilities_t security_capabilities;
|
||||||
//NSA block
|
//NSA block
|
||||||
|
|||||||
@@ -110,6 +110,24 @@ static const uint16_t NGAP_INTEGRITY_NIA3_MASK = 0x2000;
|
|||||||
|
|
||||||
static void set_UE_security_algos(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const ngap_security_capabilities_t *cap);
|
static void set_UE_security_algos(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const ngap_security_capabilities_t *cap);
|
||||||
|
|
||||||
|
/** @brief Validates PLMN against allowed PLMN list and returns pointer to matching PLMN
|
||||||
|
* @param rrc RRC instance
|
||||||
|
* @param plmn PLMN to validate
|
||||||
|
* @return pointer to matching PLMN in configuration, or NULL if not found */
|
||||||
|
static const plmn_id_t *get_serving_plmn(gNB_RRC_INST *rrc, const plmn_id_t *plmn)
|
||||||
|
{
|
||||||
|
// Find matching PLMN in configuration
|
||||||
|
for (int idx = 0; idx < rrc->configuration.num_plmn; idx++) {
|
||||||
|
const plmn_id_t *allowed = &rrc->configuration.plmn[idx];
|
||||||
|
if (allowed->mcc == plmn->mcc && allowed->mnc == plmn->mnc && allowed->mnc_digit_length == plmn->mnc_digit_length) {
|
||||||
|
LOG_D(NR_RRC, "PLMN (MCC:%d, MNC:%*d) matched with allowed PLMN[%d]\n", plmn->mcc, plmn->mnc_digit_length, plmn->mnc, idx);
|
||||||
|
return allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_W(NR_RRC, "PLMN (MCC:%d, MNC:%*d) not found in allowed PLMN list\n", plmn->mcc, plmn->mnc_digit_length, plmn->mnc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*\brief save security key.
|
*\brief save security key.
|
||||||
*\param UE UE context.
|
*\param UE UE context.
|
||||||
@@ -165,9 +183,7 @@ static nr_guami_t get_guami(const uint32_t amf_Id, const plmn_id_t plmn)
|
|||||||
guami.amf_region_id = (amf_Id >> 16) & 0xff;
|
guami.amf_region_id = (amf_Id >> 16) & 0xff;
|
||||||
guami.amf_set_id = (amf_Id >> 6) & 0x3ff;
|
guami.amf_set_id = (amf_Id >> 6) & 0x3ff;
|
||||||
guami.amf_pointer = amf_Id & 0x3f;
|
guami.amf_pointer = amf_Id & 0x3f;
|
||||||
guami.mcc = plmn.mcc;
|
guami.plmn = plmn;
|
||||||
guami.mnc = plmn.mnc;
|
|
||||||
guami.mnc_len = plmn.mnc_digit_length;
|
|
||||||
return guami;
|
return guami;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,17 +239,22 @@ void rrc_gNB_send_NGAP_NAS_FIRST_REQ(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRC
|
|||||||
req->nas_pdu = create_byte_array(rrcSetupComplete->dedicatedNAS_Message.size, rrcSetupComplete->dedicatedNAS_Message.buf);
|
req->nas_pdu = create_byte_array(rrcSetupComplete->dedicatedNAS_Message.size, rrcSetupComplete->dedicatedNAS_Message.buf);
|
||||||
|
|
||||||
/* Selected PLMN Identity (Optional)
|
/* Selected PLMN Identity (Optional)
|
||||||
* selectedPLMN-Identity in RRCSetupComplete: Index of the PLMN selected by the UE from the plmn-IdentityInfoList (SIB1)
|
* selectedPLMN-Identity in RRCSetupComplete: Index of the PLMN selected by the UE from the plmn-IdentityInfoList (SIB1) */
|
||||||
* Selected PLMN Identity in INITIAL UE MESSAGE: Indicates the selected PLMN id for the non-3GPP access.*/
|
int idx = rrcSetupComplete->selectedPLMN_Identity - 1; // Convert 1-based PLMN Identity IE to 0-based index
|
||||||
if (rrcSetupComplete->selectedPLMN_Identity > rrc->configuration.num_plmn) {
|
if (idx < 0 || idx >= rrc->configuration.num_plmn) {
|
||||||
LOG_E(NGAP,
|
LOG_E(NGAP,
|
||||||
"Failed to send Initial UE Message: selected PLMN (%ld) identity is out of bounds (%d)\n",
|
"Failed to send Initial UE Message: selected PLMN index (%d) is out of bounds [0..%d)\n",
|
||||||
rrcSetupComplete->selectedPLMN_Identity,
|
idx,
|
||||||
rrc->configuration.num_plmn);
|
rrc->configuration.num_plmn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1; // Convert 1-based PLMN Identity IE to 0-based index
|
req->plmn = rrc->configuration.plmn[idx]; // Select from the stored list
|
||||||
req->plmn = rrc->configuration.plmn[selected_plmn_identity]; // Select from the stored list
|
/* UE is connected to only one PLMN at a time: store this as the serving PLMN */
|
||||||
|
UE->serving_plmn = req->plmn;
|
||||||
|
|
||||||
|
// Cell ID (NR CGI)
|
||||||
|
req->nr_cell_id = UE->nr_cellid;
|
||||||
|
// PLMN (NR CGI and TAI)
|
||||||
plmn_id_t *p = &req->plmn;
|
plmn_id_t *p = &req->plmn;
|
||||||
LOG_I(NGAP, "Selected PLMN in the NG Initial UE Message: MCC=%03d MNC=%0*d\n", p->mcc, p->mnc_digit_length, p->mnc);
|
LOG_I(NGAP, "Selected PLMN in the NG Initial UE Message: MCC=%03d MNC=%0*d\n", p->mcc, p->mnc_digit_length, p->mnc);
|
||||||
|
|
||||||
@@ -721,6 +742,10 @@ void rrc_gNB_send_NGAP_UPLINK_NAS(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_
|
|||||||
NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id;
|
NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||||
NGAP_UPLINK_NAS(msg_p).nas_pdu.len = nas->size;
|
NGAP_UPLINK_NAS(msg_p).nas_pdu.len = nas->size;
|
||||||
NGAP_UPLINK_NAS(msg_p).nas_pdu.buf = buf;
|
NGAP_UPLINK_NAS(msg_p).nas_pdu.buf = buf;
|
||||||
|
/* Fill PLMN and location info: use serving PLMN of the UE */
|
||||||
|
NGAP_UPLINK_NAS(msg_p).plmn = UE->serving_plmn;
|
||||||
|
NGAP_UPLINK_NAS(msg_p).nr_cell_id = rrc->nr_cellid;
|
||||||
|
NGAP_UPLINK_NAS(msg_p).tac = rrc->configuration.tac;
|
||||||
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
|
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1154,6 +1179,20 @@ int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, nga
|
|||||||
rrc_gNB_send_NGAP_HANDOVER_FAILURE(rrc, &fail);
|
rrc_gNB_send_NGAP_HANDOVER_FAILURE(rrc, &fail);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate PLMN from GUAMI against allowed PLMN list
|
||||||
|
const plmn_id_t *serving_plmn = get_serving_plmn(rrc, &msg->guami.plmn);
|
||||||
|
if (!serving_plmn) {
|
||||||
|
LOG_E(NR_RRC, "PLMN from GUAMI not supported - rejecting handover\n");
|
||||||
|
ngap_handover_failure_t fail = {
|
||||||
|
.amf_ue_ngap_id = msg->amf_ue_ngap_id,
|
||||||
|
.cause.type = NGAP_CAUSE_RADIO_NETWORK,
|
||||||
|
.cause.value = NGAP_CAUSE_RADIO_NETWORK_HO_TARGET_NOT_ALLOWED,
|
||||||
|
};
|
||||||
|
rrc_gNB_send_NGAP_HANDOVER_FAILURE(rrc, &fail);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t pci = du->setup_req->cell[0].info.nr_pci;
|
uint16_t pci = du->setup_req->cell[0].info.nr_pci;
|
||||||
LOG_I(NR_RRC, "Received Handover Request (on NR Cell ID=%lu, PCI=%u) \n", msg->nr_cell_id, pci);
|
LOG_I(NR_RRC, "Received Handover Request (on NR Cell ID=%lu, PCI=%u) \n", msg->nr_cell_id, pci);
|
||||||
|
|
||||||
@@ -1169,6 +1208,9 @@ int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, nga
|
|||||||
// Store IDs in UE context
|
// Store IDs in UE context
|
||||||
UE->amf_ue_ngap_id = msg->amf_ue_ngap_id;
|
UE->amf_ue_ngap_id = msg->amf_ue_ngap_id;
|
||||||
UE->ue_guami = msg->guami;
|
UE->ue_guami = msg->guami;
|
||||||
|
// Store the serving PLMN
|
||||||
|
UE->serving_plmn = *serving_plmn;
|
||||||
|
|
||||||
UE->ho_context->target->ue_ho_prep_info = copy_byte_array(msg->ue_ho_prep_info);
|
UE->ho_context->target->ue_ho_prep_info = copy_byte_array(msg->ue_ho_prep_info);
|
||||||
// store the received UE Security Capabilities in the UE context
|
// store the received UE Security Capabilities in the UE context
|
||||||
FREE_AND_ZERO_BYTE_ARRAY(UE->ue_cap_buffer);
|
FREE_AND_ZERO_BYTE_ARRAY(UE->ue_cap_buffer);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ ngap_cause_t decode_ngap_cause(const NGAP_Cause_t *in)
|
|||||||
nr_guami_t decode_ngap_guami(const NGAP_GUAMI_t *in)
|
nr_guami_t decode_ngap_guami(const NGAP_GUAMI_t *in)
|
||||||
{
|
{
|
||||||
nr_guami_t out = {0};
|
nr_guami_t out = {0};
|
||||||
TBCD_TO_MCC_MNC(&in->pLMNIdentity, out.mcc, out.mnc, out.mnc_len);
|
TBCD_TO_MCC_MNC(&in->pLMNIdentity, out.plmn.mcc, out.plmn.mnc, out.plmn.mnc_digit_length);
|
||||||
OCTET_STRING_TO_INT8(&in->aMFRegionID, out.amf_region_id);
|
OCTET_STRING_TO_INT8(&in->aMFRegionID, out.amf_region_id);
|
||||||
OCTET_STRING_TO_INT16(&in->aMFSetID, out.amf_set_id);
|
OCTET_STRING_TO_INT16(&in->aMFSetID, out.amf_set_id);
|
||||||
OCTET_STRING_TO_INT8(&in->aMFPointer, out.amf_pointer);
|
OCTET_STRING_TO_INT8(&in->aMFPointer, out.amf_pointer);
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ static ngap_gNB_amf_data_t *select_amf(ngap_gNB_instance_t *instance_p, const ng
|
|||||||
const nr_guami_t *guami = &msg->ue_identity.guami;
|
const nr_guami_t *guami = &msg->ue_identity.guami;
|
||||||
LOG_D(NGAP,
|
LOG_D(NGAP,
|
||||||
"GUAMI is present: MCC=%03d MNC=%0*d RegionID=%d SetID=%d Pointer=%d\n",
|
"GUAMI is present: MCC=%03d MNC=%0*d RegionID=%d SetID=%d Pointer=%d\n",
|
||||||
guami->mcc,
|
guami->plmn.mcc,
|
||||||
guami->mnc_len,
|
guami->plmn.mnc_digit_length,
|
||||||
guami->mnc,
|
guami->plmn.mnc,
|
||||||
guami->amf_region_id,
|
guami->amf_region_id,
|
||||||
guami->amf_set_id,
|
guami->amf_set_id,
|
||||||
guami->amf_pointer);
|
guami->amf_pointer);
|
||||||
@@ -89,9 +89,9 @@ static ngap_gNB_amf_data_t *select_amf(ngap_gNB_instance_t *instance_p, const ng
|
|||||||
msg->gNB_ue_ngap_id,
|
msg->gNB_ue_ngap_id,
|
||||||
amf->amf_name,
|
amf->amf_name,
|
||||||
amf->assoc_id,
|
amf->assoc_id,
|
||||||
guami->mcc,
|
guami->plmn.mcc,
|
||||||
guami->mnc_len,
|
guami->plmn.mnc_digit_length,
|
||||||
guami->mnc,
|
guami->plmn.mnc,
|
||||||
guami->amf_region_id,
|
guami->amf_region_id,
|
||||||
guami->amf_set_id,
|
guami->amf_set_id,
|
||||||
guami->amf_pointer);
|
guami->amf_pointer);
|
||||||
@@ -181,7 +181,6 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
|
|||||||
.amf_ref = amf,
|
.amf_ref = amf,
|
||||||
.gNB_ue_ngap_id = UEfirstReq->gNB_ue_ngap_id,
|
.gNB_ue_ngap_id = UEfirstReq->gNB_ue_ngap_id,
|
||||||
.gNB_instance = instance_p,
|
.gNB_instance = instance_p,
|
||||||
.selected_plmn_identity = UEfirstReq->plmn,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// RAN UE NGAP ID (M)
|
// RAN UE NGAP ID (M)
|
||||||
@@ -211,16 +210,14 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
|
|||||||
ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR;
|
ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR;
|
||||||
asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p);
|
asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p);
|
||||||
|
|
||||||
/* Set nRCellIdentity. default userLocationInformationNR */
|
/* NR CGI: use gNB ID and Cell ID passed from RRC */
|
||||||
MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id,
|
MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, UEfirstReq->nr_cell_id, &userinfo_nr_p->nR_CGI.nRCellIdentity);
|
||||||
0, // Cell ID
|
|
||||||
&userinfo_nr_p->nR_CGI.nRCellIdentity);
|
|
||||||
|
|
||||||
plmn_id_t *plmn = &ue_desc_p.selected_plmn_identity;
|
/* Use UE's selected PLMN for nR-CGI (from Initial UE Message) */
|
||||||
|
plmn_id_t *plmn = &UEfirstReq->plmn;
|
||||||
MCC_MNC_TO_TBCD(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity);
|
MCC_MNC_TO_TBCD(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity);
|
||||||
|
|
||||||
/* In case of network sharing,
|
/* Set TAI - use UE's selected PLMN */
|
||||||
the selected PLMN is indicated by the PLMN Identity IE within the TAI IE */
|
|
||||||
INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC);
|
INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC);
|
||||||
MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity);
|
MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity);
|
||||||
}
|
}
|
||||||
@@ -444,17 +441,20 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_
|
|||||||
ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR;
|
ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR;
|
||||||
asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p);
|
asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p);
|
||||||
|
|
||||||
/* Set nRCellIdentity. default userLocationInformationNR */
|
/* Set nRCellIdentity: use gNB ID and Cell ID */
|
||||||
MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id,
|
MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id,
|
||||||
0, // Cell ID
|
ngap_uplink_nas_p->nr_cell_id,
|
||||||
&userinfo_nr_p->nR_CGI.nRCellIdentity);
|
&userinfo_nr_p->nR_CGI.nRCellIdentity);
|
||||||
plmn_id_t *plmn = &ue_context_p->selected_plmn_identity;
|
|
||||||
|
/* NR CGI */
|
||||||
|
plmn_id_t *plmn = &ngap_uplink_nas_p->plmn;
|
||||||
MCC_MNC_TO_TBCD(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity);
|
MCC_MNC_TO_TBCD(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity);
|
||||||
|
|
||||||
/* Set TAI */
|
/* TAI */
|
||||||
INT24_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &userinfo_nr_p->tAI.tAC);
|
INT24_TO_OCTET_STRING(ngap_uplink_nas_p->tac, &userinfo_nr_p->tAI.tAC);
|
||||||
MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity);
|
MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
|
if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
|
||||||
NGAP_ERROR("Failed to encode uplink NAS transport\n");
|
NGAP_ERROR("Failed to encode uplink NAS transport\n");
|
||||||
/* Encode procedure has failed... */
|
/* Encode procedure has failed... */
|
||||||
|
|||||||
@@ -286,8 +286,7 @@ ngap_gNB_amf_data_t *ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *inst
|
|||||||
struct plmn_identity_s *served_plmn_p = NULL;
|
struct plmn_identity_s *served_plmn_p = NULL;
|
||||||
|
|
||||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||||
if ((served_plmn_p->mcc == guami.mcc) &&
|
if ((served_plmn_p->mcc == guami.plmn.mcc) && (served_plmn_p->mnc == guami.plmn.mnc)) {
|
||||||
(served_plmn_p->mnc == guami.mnc)) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,9 +321,9 @@ ngap_gNB_amf_data_t *ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *inst
|
|||||||
}
|
}
|
||||||
|
|
||||||
NGAP_WARN("No matching AMF found for GUAMI (MCC=%03d MNC=%0*d RegionID=%d SetID=%d Pointer=%d)\n",
|
NGAP_WARN("No matching AMF found for GUAMI (MCC=%03d MNC=%0*d RegionID=%d SetID=%d Pointer=%d)\n",
|
||||||
guami.mcc,
|
guami.plmn.mcc,
|
||||||
guami.mnc_len,
|
guami.plmn.mnc_digit_length,
|
||||||
guami.mnc,
|
guami.plmn.mnc,
|
||||||
guami.amf_region_id,
|
guami.amf_region_id,
|
||||||
guami.amf_set_id,
|
guami.amf_set_id,
|
||||||
guami.amf_pointer);
|
guami.amf_pointer);
|
||||||
@@ -373,8 +372,7 @@ ngap_gNB_amf_data_t *ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instanc
|
|||||||
struct plmn_identity_s *served_plmn_p = NULL;
|
struct plmn_identity_s *served_plmn_p = NULL;
|
||||||
|
|
||||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||||
if ((served_plmn_p->mcc == guami.mcc) &&
|
if ((served_plmn_p->mcc == guami.plmn.mcc) && (served_plmn_p->mnc == guami.plmn.mnc)) {
|
||||||
(served_plmn_p->mnc == guami.mnc)) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,11 +69,6 @@ typedef struct ngap_gNB_ue_context_s {
|
|||||||
/* Reference to AMF data this UE is attached to */
|
/* Reference to AMF data this UE is attached to */
|
||||||
struct ngap_gNB_amf_data_s *amf_ref;
|
struct ngap_gNB_amf_data_s *amf_ref;
|
||||||
|
|
||||||
/* Signaled by the UE in RRC Connection Setup Complete and used in NAS Uplink
|
|
||||||
* to route NAS messages correctly. 0-based, not 1-based as in TS 36.331
|
|
||||||
* 6.2.2 RRC Connection Setup Complete! */
|
|
||||||
plmn_id_t selected_plmn_identity;
|
|
||||||
|
|
||||||
/* Reference to gNB data this UE is attached to */
|
/* Reference to gNB data this UE is attached to */
|
||||||
ngap_gNB_instance_t *gNB_instance;
|
ngap_gNB_instance_t *gNB_instance;
|
||||||
} ngap_gNB_ue_context_t;
|
} ngap_gNB_ue_context_t;
|
||||||
|
|||||||
Reference in New Issue
Block a user