mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-14 13:10:28 +00:00
Compare commits
34 Commits
pre-commit
...
telnet_o1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bd0ce22a7 | ||
|
|
dad9c796cb | ||
|
|
0c5fe22b79 | ||
|
|
3d05d940a3 | ||
|
|
a76674be42 | ||
|
|
f82476025c | ||
|
|
5ba0f11ef3 | ||
|
|
48e1468039 | ||
|
|
20b62f34a3 | ||
|
|
2413dc74bd | ||
|
|
c03e77b458 | ||
|
|
0de72f9e1f | ||
|
|
3b265e6c5c | ||
|
|
14dcc97a99 | ||
|
|
ef11cac4c6 | ||
|
|
11dd6491ee | ||
|
|
6282c26de2 | ||
|
|
c493e7994c | ||
|
|
c5da7ac9ad | ||
|
|
a08fa58ebd | ||
|
|
aa58389ff0 | ||
|
|
910e842049 | ||
|
|
c6ef9c3baf | ||
|
|
b264f4aebf | ||
|
|
dd01c029d8 | ||
|
|
98cbf6c080 | ||
|
|
e1640d89b4 | ||
|
|
b5499e1412 | ||
|
|
2270cd4cfa | ||
|
|
45546102d7 | ||
|
|
2da515e51c | ||
|
|
5881077e86 | ||
|
|
e44d68287e | ||
|
|
965ed3e8d3 |
234
ci-scripts/conf_files/du.sa.band78.51prb.rfsim.conf
Normal file
234
ci-scripts/conf_files/du.sa.band78.51prb.rfsim.conf
Normal file
@@ -0,0 +1,234 @@
|
||||
Active_gNBs = ( "du-rfsim");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_DU_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "du-rfsim";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
min_rxtxtime = 6;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3410.4 MHz => 301 REs from PointA 25 PRBs + 1 RE
|
||||
absoluteFrequencySSB = 627360;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3410.4 - (51*12*30e-3/2) = 3401.22 MHz
|
||||
dl_absoluteFrequencyPointA = 626748;
|
||||
#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=0,L=50 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 13750;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 11; # this means shift of 14, so Coreset is in PRBs 1..48, SSB starts at PRB 15
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
#pdsch-ConfigCommon
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#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 = 100;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 15;
|
||||
preambleReceivedTargetPower = -104;
|
||||
#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;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#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 = 3;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#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 =-96;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -96;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
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 = 5;
|
||||
nrofDownlinkSlots = 2;
|
||||
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;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "f1";
|
||||
local_n_if_name = "eth0";
|
||||
local_n_address = "192.168.71.171";
|
||||
remote_n_address = "192.168.71.150";
|
||||
local_n_portc = 500;
|
||||
local_n_portd = 2153;
|
||||
remote_n_portc = 501;
|
||||
remote_n_portd = 2153;
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 200;
|
||||
pucch0_dtx_threshold = 150;
|
||||
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 = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
rfsimulator: {
|
||||
serveraddr = "server";
|
||||
serverport = 4043;
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs"
|
||||
}
|
||||
|
||||
log_config: {
|
||||
global_log_level = "info";
|
||||
hw_log_level = "info";
|
||||
phy_log_level = "info";
|
||||
mac_log_level = "info";
|
||||
rlc_log_level = "info";
|
||||
f1ap_log_level = "info";
|
||||
};
|
||||
@@ -16,7 +16,7 @@ gNBs =
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }, { sst = 2 }, { sst = 3 }) });
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
@@ -15,7 +15,7 @@ gNBs =
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }, { sst = 2 }, { sst = 3 } ) });
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
235
ci-scripts/conf_files/gnb-du.sa.band78.51prb.rfsim.conf
Normal file
235
ci-scripts/conf_files/gnb-du.sa.band78.51prb.rfsim.conf
Normal file
@@ -0,0 +1,235 @@
|
||||
Active_gNBs = ( "du-rfsim");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_DU_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "du-rfsim";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
min_rxtxtime = 6;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3410.4 MHz => 301 REs from PointA 25 PRBs + 1 RE
|
||||
absoluteFrequencySSB = 630048;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3410.4 - (51*12*30e-3/2) = 3401.22 MHz
|
||||
dl_absoluteFrequencyPointA = 629436;
|
||||
#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=0,L=50 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 13750;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 11; # this means shift of 14, so Coreset is in PRBs 1..48, SSB starts at PRB 15
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
#pdsch-ConfigCommon
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#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 = 100;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 15;
|
||||
preambleReceivedTargetPower = -104;
|
||||
#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;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#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 = 3;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#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 =-96;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -96;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
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 = 5;
|
||||
nrofDownlinkSlots = 2;
|
||||
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;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "f1";
|
||||
local_n_if_name = "eth0";
|
||||
local_n_address = "192.168.71.171";
|
||||
remote_n_address = "192.168.71.150";
|
||||
local_n_portc = 500;
|
||||
local_n_portd = 2153;
|
||||
remote_n_portc = 501;
|
||||
remote_n_portd = 2153;
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 200;
|
||||
pucch0_dtx_threshold = 150;
|
||||
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 = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
rfsimulator: {
|
||||
serveraddr = "server";
|
||||
serverport = 4043;
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs"
|
||||
}
|
||||
|
||||
log_config: {
|
||||
global_log_level = "info";
|
||||
hw_log_level = "info";
|
||||
phy_log_level = "info";
|
||||
mac_log_level = "info";
|
||||
rlc_log_level = "info";
|
||||
f1ap_log_level = "info";
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
Active_gNBs = ( "gNB-in-docker");
|
||||
Active_gNBs = ( "gNB-DU-in-docker");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
@@ -6,17 +6,32 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "gNB-in-docker";
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "gNB-DU-in-docker";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 222; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
|
||||
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
#min_rxtxtime = 6;
|
||||
force_256qam_off = 0;
|
||||
|
||||
do_CSIRS = 0;
|
||||
do_SRS = 0;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
@@ -156,36 +171,35 @@ gNBs =
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "172.21.16.137";
|
||||
amf_ip_address = ( { ipv4 = "192.168.70.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "eth0";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.68.194";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "eth0";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.68.194";
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "10.0.0.2";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "10.0.0.2";
|
||||
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;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
}
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 230; # 200; after test in lab
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 1;
|
||||
ul_max_mcs = 16;
|
||||
min_grant_prb = 20;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
@@ -203,11 +217,11 @@ RUs = (
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 14;
|
||||
att_rx = 14;
|
||||
att_tx = 6; # 8; after test in lab
|
||||
att_rx = 6; # 8; after test in lab
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
max_rxgain = 120;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
@@ -224,22 +238,6 @@ THREAD_STRUCT = (
|
||||
}
|
||||
);
|
||||
|
||||
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 :
|
||||
{
|
||||
@@ -250,6 +248,6 @@ log_config :
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="debug";
|
||||
ngap_log_level ="info";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
386
ci-scripts/yaml_files/5g_rfsimulator_o1/README.md
Normal file
386
ci-scripts/yaml_files/5g_rfsimulator_o1/README.md
Normal file
@@ -0,0 +1,386 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">Testing O1 in containers</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
|
||||
# 1. Deploy containers #
|
||||
|
||||
## 2.1. Deploy OAI 5G Core Network ##
|
||||
|
||||
```bash
|
||||
docker-compose up -d mysql oai-amf oai-smf oai-upf oai-ext-dn
|
||||
[+] Running 12/12
|
||||
✔ Network rfsim5g-oai-core-net Created 0.1s
|
||||
✔ Network rfsim5g-oai-traffic-net Created 0.1s
|
||||
✔ Network rfsim5g-oai-e1-net Created 0.1s
|
||||
✔ Network rfsim5g-oai-f1u-1-net Created 0.1s
|
||||
✔ Network rfsim5g-oai-f1c-net Created 0.1s
|
||||
✔ Network rfsim5g-oai-ue-net Created 0.1s
|
||||
✔ Network rfsim5g-oai-o1-net Created 0.1s
|
||||
✔ Container rfsim5g-mysql Started 0.3s
|
||||
✔ Container rfsim5g-oai-amf Started 0.5s
|
||||
✔ Container rfsim5g-oai-smf Started 0.7s
|
||||
✔ Container rfsim5g-oai-upf Started 0.9s
|
||||
✔ Container rfsim5g-oai-ext-dn Started 1.1s
|
||||
```
|
||||
|
||||
```bash
|
||||
docker-compose ps -a
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
rfsim5g-mysql mysql:8.0 "docker-entrypoint.s…" mysql About a minute ago Up About a minute (healthy) 3306/tcp, 33060/tcp
|
||||
rfsim5g-oai-amf oaisoftwarealliance/oai-amf:v2.0.0 "/openair-amf/bin/oa…" oai-amf About a minute ago Up About a minute (healthy) 80/tcp, 9090/tcp, 38412/sctp
|
||||
rfsim5g-oai-ext-dn oaisoftwarealliance/trf-gen-cn5g:focal "/bin/bash -c ' ipta…" oai-ext-dn About a minute ago Up About a minute (healthy)
|
||||
rfsim5g-oai-smf oaisoftwarealliance/oai-smf:v2.0.0 "/openair-smf/bin/oa…" oai-smf About a minute ago Up About a minute (healthy) 80/tcp, 8080/tcp, 8805/udp
|
||||
rfsim5g-oai-upf oaisoftwarealliance/oai-upf:v2.0.0 "/openair-upf/bin/oa…" oai-upf About a minute ago Up About a minute (healthy) 2152/udp, 8805/udp
|
||||
```
|
||||
|
||||
## 2.2. Deploy OAI CU-CP, CU-UP and DU ##
|
||||
|
||||
|
||||
```bash
|
||||
docker-compose up -d oai-cu-cp oai-cu-up oai-du
|
||||
[+] Running 7/7
|
||||
✔ Container rfsim5g-mysql Running 0.0s
|
||||
✔ Container rfsim5g-oai-amf Running 0.0s
|
||||
✔ Container rfsim5g-oai-smf Running 0.0s
|
||||
✔ Container rfsim5g-oai-upf Running 0.0s
|
||||
✔ Container rfsim5g-oai-cucp Started 0.4s
|
||||
✔ Container rfsim5g-oai-cuup Started 0.8s
|
||||
✔ Container rfsim5g-oai-du Started 1.2s
|
||||
```
|
||||
|
||||
## Check Stats via telnet O1 Module ##
|
||||
|
||||
Make sure you have installed `netcat` in your host machine or container.
|
||||
|
||||
In case you don't have then install in the gnb container
|
||||
|
||||
```bash
|
||||
docker exec -it rfsim5g-oai-du bash
|
||||
apt update -y && apt install netcat -y
|
||||
```
|
||||
|
||||
```bash
|
||||
echo o1 stats | nc -N 192.168.74.2 9090
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>The output is similar to:</summary>
|
||||
|
||||
```console
|
||||
{
|
||||
"o1-config": {
|
||||
"BWP": {
|
||||
"dl": [{
|
||||
"bwp3gpp:isInitialBwp": true,
|
||||
"bwp3gpp:numberOfRBs": 51,
|
||||
"bwp3gpp:startRB": 0,
|
||||
"bwp3gpp:subCarrierSpacing": 30
|
||||
}],
|
||||
"ul": [{
|
||||
"bwp3gpp:isInitialBwp": true,
|
||||
"bwp3gpp:numberOfRBs": 51,
|
||||
"bwp3gpp:startRB": 0,
|
||||
"bwp3gpp:subCarrierSpacing": 30
|
||||
}]
|
||||
},
|
||||
"NRCELLDU": {
|
||||
"nrcelldu3gpp:ssbFrequency": 630048,
|
||||
"nrcelldu3gpp:arfcnDL": 629436,
|
||||
"nrcelldu3gpp:bSChannelBwDL": 20,
|
||||
"nrcelldu3gpp:arfcnUL": 629436,
|
||||
"nrcelldu3gpp:bSChannelBwUL": 20,
|
||||
"nrcelldu3gpp:nRPCI": 0,
|
||||
"nrcelldu3gpp:nRTAC": 1,
|
||||
"nrcelldu3gpp:mcc": "208",
|
||||
"nrcelldu3gpp:mnc": "99",
|
||||
"nrcelldu3gpp:sd": 16777215,
|
||||
"nrcelldu3gpp:sst": 1
|
||||
},
|
||||
"device": {
|
||||
"gnbId": 3584,
|
||||
"gnbName": "du-rfsim",
|
||||
"vendor": "OpenAirInterface"
|
||||
}
|
||||
},
|
||||
"O1-Operational": {
|
||||
"frame-type": "tdd",
|
||||
"band-number": 78,
|
||||
"num-ues": 0,
|
||||
"ues": [ ],
|
||||
"load": 0,
|
||||
"ues-thp": [
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
Notice the block `O1-Operational` you will see the number of connected UEs, present load at the gNB and the DL/UL RLC `throughput` in `Kbps`.
|
||||
|
||||
## Deploy OAI NR-UE in RF simulator mode and in Standalone Mode ##
|
||||
|
||||
```bash
|
||||
docker-compose up -d oai-nr-ue
|
||||
[+] Running 8/8
|
||||
✔ Container rfsim5g-mysql Running 0.0s
|
||||
✔ Container rfsim5g-oai-amf Running 0.0s
|
||||
✔ Container rfsim5g-oai-smf Running 0.0s
|
||||
✔ Container rfsim5g-oai-upf Running 0.0s
|
||||
✔ Container rfsim5g-oai-cucp Running 0.0s
|
||||
✔ Container rfsim5g-oai-cuup Running 0.0s
|
||||
✔ Container rfsim5g-oai-du Running 0.0s
|
||||
✔ Container rfsim5g-oai-nr-ue Started 0.2s
|
||||
```
|
||||
|
||||
Wait for a bit.
|
||||
|
||||
```bash
|
||||
docker-compose ps -a
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
rfsim5g-mysql mysql:8.0 "docker-entrypoint.s…" mysql 30 minutes ago Up 30 minutes (healthy) 3306/tcp, 33060/tcp
|
||||
rfsim5g-oai-amf oaisoftwarealliance/oai-amf:v2.0.0 "/openair-amf/bin/oa…" oai-amf 30 minutes ago Up 30 minutes (healthy) 80/tcp, 9090/tcp, 38412/sctp
|
||||
rfsim5g-oai-cucp arorasagar/testing-images:oai-gnb-telnet "/opt/oai-gnb/bin/en…" oai-cu-cp 29 minutes ago Up 29 minutes (healthy)
|
||||
rfsim5g-oai-cuup oaisoftwarealliance/oai-nr-cuup:v2.1.0 "/opt/oai-gnb/bin/en…" oai-cu-up 29 minutes ago Up 29 minutes (healthy)
|
||||
rfsim5g-oai-du arorasagar/testing-images:oai-gnb-telnet "/opt/oai-gnb/bin/en…" oai-du 5 minutes ago Up 5 minutes (healthy)
|
||||
rfsim5g-oai-ext-dn oaisoftwarealliance/trf-gen-cn5g:focal "/bin/bash -c ' ipta…" oai-ext-dn 30 minutes ago Up 30 minutes (healthy)
|
||||
rfsim5g-oai-nr-ue oaisoftwarealliance/oai-nr-ue:v2.1.0 "/opt/oai-nr-ue/bin/…" oai-nr-ue 4 minutes ago Up 4 minutes (healthy)
|
||||
rfsim5g-oai-smf oaisoftwarealliance/oai-smf:v2.0.0 "/openair-smf/bin/oa…" oai-smf 30 minutes ago Up 30 minutes (healthy) 80/tcp, 8080/tcp, 8805/udp
|
||||
rfsim5g-oai-upf oaisoftwarealliance/oai-upf:v2.0.0 "/openair-upf/bin/oa…" oai-upf 30 minutes ago Up 30 minutes (healthy) 2152/udp, 8805/udp
|
||||
```
|
||||
|
||||
Making sure the OAI UE is connected:
|
||||
|
||||
```bash
|
||||
docker exec -it rfsim5g-oai-nr-ue ifconfig oaitun_ue1
|
||||
oaitun_ue1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
|
||||
inet 12.1.1.2 netmask 255.255.255.0 destination 12.1.1.2
|
||||
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
|
||||
RX packets 0 bytes 0 (0.0 B)
|
||||
RX errors 0 dropped 0 overruns 0 frame 0
|
||||
TX packets 0 bytes 0 (0.0 B)
|
||||
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
||||
```
|
||||
|
||||
Now if you will re-check the stats you will see
|
||||
|
||||
```bash
|
||||
echo o1 stats | nc -N 192.168.74.2 9090
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>The output is similar to:</summary>
|
||||
|
||||
```console
|
||||
{
|
||||
"o1-config": {
|
||||
"BWP": {
|
||||
"dl": [{
|
||||
"bwp3gpp:isInitialBwp": true,
|
||||
"bwp3gpp:numberOfRBs": 51,
|
||||
"bwp3gpp:startRB": 0,
|
||||
"bwp3gpp:subCarrierSpacing": 30
|
||||
}],
|
||||
"ul": [{
|
||||
"bwp3gpp:isInitialBwp": true,
|
||||
"bwp3gpp:numberOfRBs": 51,
|
||||
"bwp3gpp:startRB": 0,
|
||||
"bwp3gpp:subCarrierSpacing": 30
|
||||
}]
|
||||
},
|
||||
"NRCELLDU": {
|
||||
"nrcelldu3gpp:ssbFrequency": 627360,
|
||||
"nrcelldu3gpp:arfcnDL": 626748,
|
||||
"nrcelldu3gpp:bSChannelBwDL": 20,
|
||||
"nrcelldu3gpp:arfcnUL": 626748,
|
||||
"nrcelldu3gpp:bSChannelBwUL": 20,
|
||||
"nrcelldu3gpp:nRPCI": 0,
|
||||
"nrcelldu3gpp:nRTAC": 1,
|
||||
"nrcelldu3gpp:mcc": "208",
|
||||
"nrcelldu3gpp:mnc": "99",
|
||||
"nrcelldu3gpp:sd": 16777215,
|
||||
"nrcelldu3gpp:sst": 1
|
||||
},
|
||||
"device": {
|
||||
"gnbId": 3584,
|
||||
"gnbName": "du-rfsim",
|
||||
"vendor": "OpenAirInterface"
|
||||
}
|
||||
},
|
||||
"O1-Operational": {
|
||||
"frame-type": "tdd",
|
||||
"band-number": 78,
|
||||
"num-ues": 1,
|
||||
"ues": [39874 ],
|
||||
"load": 0,
|
||||
"ues-thp": [
|
||||
{"rnti": 39874, "dl": 0, "ul": 0}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
You can do some throughput test and check load for this you need to install `iperf3` in the UE container
|
||||
|
||||
```bash
|
||||
docker exec -it rfsim5g-oai-nr-ue bash
|
||||
apt update -y && apt install iperf3 -y
|
||||
exit
|
||||
```
|
||||
Iperf3 server is already running you can start Iperf3 client
|
||||
|
||||
```bash
|
||||
docker exec -it rfsim5g-oai-nr-ue iperf3 -B 12.1.1.2 -b 80M -c 192.168.72.135 -R -t 100
|
||||
```
|
||||
|
||||
Measure the load
|
||||
|
||||
|
||||
```bash
|
||||
echo o1 stats | nc -N 192.168.74.2 9090
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>The output is similar to:</summary>
|
||||
|
||||
```console
|
||||
"O1-Operational": {
|
||||
"frame-type": "tdd",
|
||||
"band-number": 78,
|
||||
"num-ues": 1,
|
||||
"ues": [39874 ],
|
||||
"load": 95,
|
||||
"ues-thp": [
|
||||
{"rnti": 39874, "dl": 52596, "ul": 913}
|
||||
]
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
Now re-configure the bandwidth
|
||||
|
||||
1. Stop the L1
|
||||
|
||||
```bash
|
||||
echo o1 stop_modem | nc -N 192.168.74.2 9090
|
||||
```
|
||||
|
||||
2. Reconfigure bandwidth
|
||||
|
||||
```bash
|
||||
echo o1 bwconfig 40 | nc -N 192.168.74.2 9090
|
||||
```
|
||||
|
||||
3. Start L1
|
||||
|
||||
```bash
|
||||
echo o1 start_modem | nc -N 192.168.74.2 9090
|
||||
```
|
||||
|
||||
4. Check the reconfigured bandwidth
|
||||
|
||||
```bash
|
||||
echo o1 stats | nc -N 192.168.74.2 9090
|
||||
```
|
||||
|
||||
```bash
|
||||
{
|
||||
"o1-config": {
|
||||
"BWP": {
|
||||
"dl": [{
|
||||
"bwp3gpp:isInitialBwp": true,
|
||||
"bwp3gpp:numberOfRBs": 106,
|
||||
"bwp3gpp:startRB": 0,
|
||||
"bwp3gpp:subCarrierSpacing": 30
|
||||
}],
|
||||
"ul": [{
|
||||
"bwp3gpp:isInitialBwp": true,
|
||||
"bwp3gpp:numberOfRBs": 106,
|
||||
"bwp3gpp:startRB": 0,
|
||||
"bwp3gpp:subCarrierSpacing": 30
|
||||
}]
|
||||
},
|
||||
"NRCELLDU": {
|
||||
"nrcelldu3gpp:ssbFrequency": 641280,
|
||||
"nrcelldu3gpp:arfcnDL": 640008,
|
||||
"nrcelldu3gpp:bSChannelBwDL": 40,
|
||||
"nrcelldu3gpp:arfcnUL": 640008,
|
||||
"nrcelldu3gpp:bSChannelBwUL": 40,
|
||||
"nrcelldu3gpp:nRPCI": 0,
|
||||
"nrcelldu3gpp:nRTAC": 1,
|
||||
"nrcelldu3gpp:mcc": "208",
|
||||
"nrcelldu3gpp:mnc": "99",
|
||||
"nrcelldu3gpp:sd": 16777215,
|
||||
"nrcelldu3gpp:sst": 1
|
||||
},
|
||||
"device": {
|
||||
"gnbId": 3584,
|
||||
"gnbName": "du-rfsim",
|
||||
"vendor": "OpenAirInterface"
|
||||
}
|
||||
},
|
||||
"O1-Operational": {
|
||||
"frame-type": "tdd",
|
||||
"band-number": 78,
|
||||
"num-ues": 0,
|
||||
"ues": [ ],
|
||||
"load": 14,
|
||||
"ues-thp": [
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can see `nrcelldu3gpp:bSChannelBwUL` as 40.
|
||||
|
||||
5. Re-connect UE
|
||||
|
||||
In the [docker-compose.yaml](./docker-compose.yaml) file in `oai-nr-ue` section you need to change the UE command to 40MHz bandwidth.
|
||||
|
||||
```
|
||||
# # 20 MHz
|
||||
# USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
|
||||
# -r 51 --numerology 1 -C 3450720000 --ssb 186
|
||||
# --uicc0.imsi 208990100001100
|
||||
# --rfsimulator.serveraddr 192.168.78.2
|
||||
# 40 MHz
|
||||
USE_ADDITIONAL_OPTIONS: --sa -E --rfsim --log_config.global_log_options level,nocolor,time
|
||||
-r 106 --numerology 1 -C 3619200000
|
||||
--uicc0.imsi 208990100001100
|
||||
--rfsimulator.serveraddr 192.168.78.2
|
||||
```
|
||||
|
||||
```bash
|
||||
docker rm rfsim5g-oai-nr-ue
|
||||
docker-compose up -d oai-nr-ue
|
||||
```
|
||||
|
||||
After this you can deploy the UE and again do an iperf3 test you will see the load is almost half now
|
||||
|
||||
```
|
||||
"O1-Operational": {
|
||||
"frame-type": "tdd",
|
||||
"band-number": 78,
|
||||
"num-ues": 1,
|
||||
"ues": [25333 ],
|
||||
"load": 52,
|
||||
"ues-thp": [
|
||||
{"rnti": 25333, "dl": 83266, "ul": 1123}
|
||||
]
|
||||
}
|
||||
```
|
||||
247
ci-scripts/yaml_files/5g_rfsimulator_o1/docker-compose.yaml
Normal file
247
ci-scripts/yaml_files/5g_rfsimulator_o1/docker-compose.yaml
Normal file
@@ -0,0 +1,247 @@
|
||||
services:
|
||||
mysql:
|
||||
container_name: "rfsim5g-mysql"
|
||||
image: mysql:8.0
|
||||
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"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
networks:
|
||||
core_net:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.0.0
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
- ./mini_nonrf_config.yaml:/openair-amf/etc/config.yaml
|
||||
depends_on:
|
||||
- mysql
|
||||
networks:
|
||||
core_net:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.0.0
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
- ./mini_nonrf_config.yaml:/openair-smf/etc/config.yaml
|
||||
depends_on:
|
||||
- oai-amf
|
||||
networks:
|
||||
core_net:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.0.0
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
- ./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:
|
||||
core_net:
|
||||
ipv4_address: 192.168.71.134
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.134
|
||||
oai-ext-dn:
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-ext-dn
|
||||
image: oaisoftwarealliance/trf-gen-cn5g:focal
|
||||
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; iperf3 -s -D;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"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
oai-cu-cp:
|
||||
image: arorasagar/testing-images:oai-gnb-telnet
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-cucp
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time
|
||||
--gNBs.[0].E1_INTERFACE.[0].ipv4_cucp 192.168.77.2
|
||||
--gNBs.[0].local_s_address 192.168.72.2
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
depends_on:
|
||||
- oai-upf
|
||||
networks:
|
||||
core_net:
|
||||
ipv4_address: 192.168.71.150
|
||||
f1c_net:
|
||||
ipv4_address: 192.168.72.2
|
||||
e1_net:
|
||||
ipv4_address: 192.168.77.2
|
||||
volumes:
|
||||
- ../../conf_files/gnb-cucp.sa.f1.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
oai-cu-up:
|
||||
image: oaisoftwarealliance/oai-nr-cuup:v2.1.0
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-cuup
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time
|
||||
--gNBs.[0].E1_INTERFACE.[0].ipv4_cucp 192.168.77.2
|
||||
--gNBs.[0].E1_INTERFACE.[0].ipv4_cuup 192.168.77.3
|
||||
--gNBs.[0].local_s_address 192.168.73.2
|
||||
--gNBs.[0].remote_s_address 127.0.0.1
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
depends_on:
|
||||
- oai-cu-cp
|
||||
networks:
|
||||
core_net:
|
||||
ipv4_address: 192.168.71.161
|
||||
f1u_net:
|
||||
ipv4_address: 192.168.73.2
|
||||
e1_net:
|
||||
ipv4_address: 192.168.77.3
|
||||
volumes:
|
||||
- ../../conf_files/gnb-cuup.sa.f1.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-cuup"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
oai-du:
|
||||
image: arorasagar/testing-images:oai-gnb-telnet
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-du
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
|
||||
--MACRLCs.[0].local_n_address 192.168.73.3
|
||||
--MACRLCs.[0].remote_n_address 192.168.72.2
|
||||
--telnetsrv --telnetsrv.shrmod o1 --telnetsrv.listenaddr 192.168.74.2
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
depends_on:
|
||||
- oai-cu-cp
|
||||
- oai-cu-up
|
||||
networks:
|
||||
f1c_net:
|
||||
ipv4_address: 192.168.72.3
|
||||
f1u_net:
|
||||
ipv4_address: 192.168.73.3
|
||||
o1_net:
|
||||
ipv4_address: 192.168.74.2
|
||||
ue_net:
|
||||
ipv4_address: 192.168.78.2
|
||||
volumes:
|
||||
- ../../conf_files/gnb-du.sa.band78.51prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
oai-nr-ue:
|
||||
image: oaisoftwarealliance/oai-nr-ue:v2.1.0
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-nr-ue
|
||||
environment:
|
||||
# # 20 MHz
|
||||
# USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time
|
||||
# -r 51 --numerology 1 -C 3450720000 --ssb 186
|
||||
# --uicc0.imsi 208990100001100
|
||||
# --rfsimulator.serveraddr 192.168.78.2
|
||||
# 40 MHz
|
||||
USE_ADDITIONAL_OPTIONS: --sa -E --rfsim --log_config.global_log_options level,nocolor,time
|
||||
-r 106 --numerology 1 -C 3619200000
|
||||
--uicc0.imsi 208990100001100
|
||||
--rfsimulator.serveraddr 192.168.78.2
|
||||
depends_on:
|
||||
- oai-du
|
||||
networks:
|
||||
ue_net:
|
||||
ipv4_address: 192.168.78.5
|
||||
volumes:
|
||||
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-uesoftmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
core_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-core-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.71.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-core"
|
||||
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"
|
||||
f1c_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-f1c-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.72.0/28
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-f1c"
|
||||
f1u_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-f1u-1-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.73.0/28
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-f1u"
|
||||
o1_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-o1-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.74.0/28
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-o1"
|
||||
e1_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-e1-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.77.0/28
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-e1"
|
||||
ue_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-ue-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.78.0/28
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-ue"
|
||||
189
ci-scripts/yaml_files/5g_rfsimulator_o1/mini_nonrf_config.yaml
Normal file
189
ci-scripts/yaml_files/5g_rfsimulator_o1/mini_nonrf_config.yaml
Normal file
@@ -0,0 +1,189 @@
|
||||
################################################################################
|
||||
# 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
|
||||
################################################################################
|
||||
|
||||
# OAI CN Configuration File
|
||||
### This file can be used by all OAI NFs
|
||||
### Some fields are specific to an NF and will be ignored by other NFs
|
||||
|
||||
## NOTE ON YAML ANCHORS ##
|
||||
# We use YAML anchors to ease the configuration and to avoid duplicating parts of the configuration.
|
||||
# This is especially true for the SNSSAIs, as we have to define them for multiple NFs.
|
||||
# Please note that the use of anchors is not mandatory, and you can define the SNSSAI in each NF yourself.
|
||||
# You can read more about anchors here: https://yaml.org/spec/1.2.2/#anchors-and-aliases
|
||||
|
||||
############# Common configuration
|
||||
|
||||
# Log level for all the NFs
|
||||
log_level:
|
||||
general: debug
|
||||
|
||||
# If you enable registration, the other NFs will use the NRF discovery mechanism
|
||||
register_nf:
|
||||
general: no
|
||||
|
||||
http_version: 1
|
||||
|
||||
############## SBI Interfaces
|
||||
### Each NF takes its local SBI interfaces and remote interfaces from here, unless it gets them using NRF discovery mechanisms
|
||||
nfs:
|
||||
amf:
|
||||
host: oai-amf
|
||||
sbi:
|
||||
port: 80
|
||||
api_version: v1
|
||||
interface_name: eth0
|
||||
n2:
|
||||
interface_name: eth0
|
||||
port: 38412
|
||||
smf:
|
||||
host: oai-smf
|
||||
sbi:
|
||||
port: 80
|
||||
api_version: v1
|
||||
interface_name: eth0
|
||||
n4:
|
||||
interface_name: eth0
|
||||
port: 8805
|
||||
|
||||
upf:
|
||||
host: oai-upf
|
||||
sbi:
|
||||
port: 80
|
||||
api_version: v1
|
||||
interface_name: eth0
|
||||
n3:
|
||||
interface_name: eth0
|
||||
port: 2152
|
||||
n4:
|
||||
interface_name: eth0
|
||||
port: 8805
|
||||
n6:
|
||||
interface_name: eth1
|
||||
n9:
|
||||
interface_name: eth0
|
||||
port: 2152
|
||||
|
||||
#### Common for UDR and AMF
|
||||
database:
|
||||
host: mysql
|
||||
user: test
|
||||
type: mysql
|
||||
password: test
|
||||
database_name: oai_db
|
||||
generate_random: true
|
||||
connection_timeout: 300 # seconds
|
||||
|
||||
## general single_nssai configuration
|
||||
## Defines YAML anchors, which are reused in the config file
|
||||
snssais:
|
||||
- &embb_slice1
|
||||
sst: 1
|
||||
|
||||
############## NF-specific configuration
|
||||
amf:
|
||||
amf_name: "OAI-AMF"
|
||||
# This really depends on if we want to keep the "mini" version or not
|
||||
support_features_options:
|
||||
enable_simple_scenario: yes # "no" by default with the normal deployment scenarios with AMF/SMF/UPF/AUSF/UDM/UDR/NRF.
|
||||
# set it to "yes" to use with the minimalist deployment scenario (including only AMF/SMF/UPF) by using the internal AUSF/UDM implemented inside AMF.
|
||||
# There's no NRF in this scenario, SMF info is taken from "nfs" section.
|
||||
enable_nssf: no
|
||||
enable_smf_selection: no
|
||||
relative_capacity: 30
|
||||
statistics_timer_interval: 20 # in seconds
|
||||
emergency_support: false
|
||||
served_guami_list:
|
||||
- mcc: 208
|
||||
mnc: 99
|
||||
amf_region_id: 01
|
||||
amf_set_id: 001
|
||||
amf_pointer: 01
|
||||
plmn_support_list:
|
||||
- mcc: 208
|
||||
mnc: 99
|
||||
tac: 0x0001
|
||||
nssai:
|
||||
- *embb_slice1
|
||||
supported_integrity_algorithms:
|
||||
- "NIA0"
|
||||
- "NIA1"
|
||||
- "NIA2"
|
||||
supported_encryption_algorithms:
|
||||
- "NEA0"
|
||||
- "NEA1"
|
||||
- "NEA2"
|
||||
|
||||
smf:
|
||||
ue_mtu: 1500
|
||||
support_features:
|
||||
use_local_subscription_info: yes # Use infos from local_subscription_info or from UDM
|
||||
use_local_pcc_rules: yes # Use infos from local_pcc_rules or from PCF
|
||||
upfs:
|
||||
- host: oai-upf
|
||||
port: 8805
|
||||
config:
|
||||
enable_usage_reporting: no
|
||||
# follows UPFInfo from 3GPP TS 29.510, currently only these values from interfaceUpfInfoList are supported
|
||||
upf_info:
|
||||
interfaceUpfInfoList:
|
||||
- interfaceType: "N3"
|
||||
networkInstance: "access.oai.org"
|
||||
- interfaceType: "N6"
|
||||
networkInstance: "core.oai.org"
|
||||
ue_dns:
|
||||
primary_ipv4: "172.21.3.100"
|
||||
primary_ipv6: "2001:4860:4860::8888"
|
||||
secondary_ipv4: "8.8.8.8"
|
||||
secondary_ipv6: "2001:4860:4860::8888"
|
||||
ims:
|
||||
pcscf_ipv4: "127.0.0.1"
|
||||
pcscf_ipv6: "fe80::7915:f408:1787:db8b"
|
||||
# the DNN you configure here should be configured in "dnns"
|
||||
# follows the SmfInfo datatype from 3GPP TS 29.510
|
||||
smf_info:
|
||||
sNssaiSmfInfoList:
|
||||
- sNssai: *embb_slice1
|
||||
dnnSmfInfoList:
|
||||
- dnn: "oai"
|
||||
local_subscription_infos:
|
||||
- single_nssai: *embb_slice1
|
||||
dnn: "oai"
|
||||
qos_profile:
|
||||
5qi: 9
|
||||
session_ambr_ul: "200Mbps"
|
||||
session_ambr_dl: "400Mbps"
|
||||
|
||||
upf:
|
||||
support_features:
|
||||
enable_bpf_datapath: no # If "on": BPF is used as datapath else simpleswitch is used, DEFAULT= off
|
||||
enable_snat: yes # If "on": Source natting is done for UE, DEFAULT= off
|
||||
remote_n6_gw: 127.0.0.1 # Dummy host since simple-switch does not use N6 GW
|
||||
upf_info:
|
||||
sNssaiUpfInfoList:
|
||||
- sNssai: *embb_slice1
|
||||
dnnUpfInfoList:
|
||||
- dnn: "oai"
|
||||
|
||||
## DNN configuration
|
||||
dnns:
|
||||
- dnn: "oai"
|
||||
pdu_session_type: "IPV4"
|
||||
ipv4_subnet: "12.1.1.0/24"
|
||||
46
ci-scripts/yaml_files/5g_rfsimulator_o1/mysql-healthcheck.sh
Executable file
46
ci-scripts/yaml_files/5g_rfsimulator_o1/mysql-healthcheck.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
|
||||
if [ "$MYSQL_ROOT_PASSWORD" ] && [ -z "$MYSQL_USER" ] && [ -z "$MYSQL_PASSWORD" ]; then
|
||||
echo >&2 'Healthcheck error: cannot determine root password (and MYSQL_USER and MYSQL_PASSWORD were not set)'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
host="$(hostname --ip-address || echo '127.0.0.1')"
|
||||
user="${MYSQL_USER:-root}"
|
||||
export MYSQL_PWD="${MYSQL_PASSWORD:-$MYSQL_ROOT_PASSWORD}"
|
||||
|
||||
args=(
|
||||
# force mysql to not use the local "mysqld.sock" (test "external" connectivity)
|
||||
-h"$host"
|
||||
-u"$user"
|
||||
--silent
|
||||
)
|
||||
|
||||
STATUS=0
|
||||
if command -v mysqladmin &> /dev/null; then
|
||||
if mysqladmin "${args[@]}" ping > /dev/null; then
|
||||
database_check=$(mysql -u$user -D oai_db --silent -e "SELECT * FROM users;")
|
||||
if [[ -z $database_check ]]; then
|
||||
echo "Healthcheck error: oai_db not populated"
|
||||
STATUS=1
|
||||
fi
|
||||
STATUS=0
|
||||
else
|
||||
echo "Healthcheck error: Mysql port inactive"
|
||||
STATUS=1
|
||||
fi
|
||||
else
|
||||
if select="$(echo 'SELECT 1' | mysql "${args[@]}")" && [ "$select" = '1' ]; then
|
||||
database_check=$(mysql -u$user -D oai_db --silent -e "SELECT * FROM users;")
|
||||
if [[ -z $database_check ]]; then
|
||||
echo "Healthcheck error: oai_db not populated"
|
||||
STATUS=1
|
||||
fi
|
||||
STATUS=0
|
||||
else
|
||||
echo "Healthcheck error: Mysql port inactive"
|
||||
STATUS=1
|
||||
fi
|
||||
fi
|
||||
exit $STATUS
|
||||
232
ci-scripts/yaml_files/5g_rfsimulator_o1/oai_db.sql
Normal file
232
ci-scripts/yaml_files/5g_rfsimulator_o1/oai_db.sql
Normal file
File diff suppressed because one or more lines are too long
@@ -112,6 +112,7 @@ void *config_allocate_new(configmodule_interface_t *cfg, int sz, bool autoFree)
|
||||
// add the memory piece in the managed memory pieces list
|
||||
pthread_mutex_lock(&cfg->memBlocks_mutex);
|
||||
int newBlockIdx=cfg->numptrs++;
|
||||
AssertFatal(newBlockIdx <= sizeof(cfg->oneBlock) / sizeof(cfg->oneBlock[0]), "reached maximum number of dynamically allocatable blocks\n");
|
||||
oneBlock_t* tmp=&cfg->oneBlock[newBlockIdx];
|
||||
tmp->ptrs = (char *)ptr;
|
||||
tmp->ptrsAllocated = true;
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include "common/config/config_paramdesc.h"
|
||||
#include "common/utils/T/T.h"
|
||||
#define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2...
|
||||
#define CONFIG_MAX_ALLOCATEDPTRS 2048 // maximum number of parameters that can be dynamicaly allocated in the config module
|
||||
#define CONFIG_MAX_ALLOCATEDPTRS 32768 // maximum number of parameters that can be dynamicaly allocated in the config module
|
||||
|
||||
/* default values for configuration module parameters */
|
||||
#define CONFIG_LIBCONFIGFILE "libconfig" // use libconfig file
|
||||
|
||||
@@ -411,7 +411,7 @@ frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index)
|
||||
else
|
||||
current_type = FDD;
|
||||
|
||||
LOG_I(NR_MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex);
|
||||
LOG_D(NR_MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex);
|
||||
|
||||
return current_type;
|
||||
}
|
||||
@@ -423,7 +423,7 @@ int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index)
|
||||
|
||||
int32_t delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min);
|
||||
|
||||
LOG_I(NR_MAC, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band);
|
||||
LOG_D(NR_MAC, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band);
|
||||
|
||||
return delta_duplex;
|
||||
}
|
||||
|
||||
@@ -64,8 +64,14 @@ add_library(telnetsrv_bearer MODULE telnetsrv_bearer.c)
|
||||
target_link_libraries(telnetsrv_bearer PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
add_dependencies(telnetsrv telnetsrv_bearer)
|
||||
|
||||
message(STATUS "Add CI specific telnet functions in libtelnetsrv_o1.so")
|
||||
add_library(telnetsrv_o1 MODULE telnetsrv_o1.c)
|
||||
target_link_libraries(telnetsrv_o1 PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
add_dependencies(telnetsrv telnetsrv_o1)
|
||||
|
||||
# all libraries should be written to root build dir
|
||||
set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci telnetsrv_bearer
|
||||
telnetsrv_o1
|
||||
PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../../..
|
||||
)
|
||||
|
||||
|
||||
185
common/utils/telnetsrv/DOC/telneto1.md
Normal file
185
common/utils/telnetsrv/DOC/telneto1.md
Normal file
@@ -0,0 +1,185 @@
|
||||
[[_TOC_]]
|
||||
|
||||
The telnet O1 module (`telnetsrv_o1.c`) can be used to perform some O1-related
|
||||
actions (reading data, starting and stopping the nr-softmodem, reconfigurating
|
||||
frequency and bandwidth).
|
||||
|
||||
# General usage
|
||||
|
||||
The usage is similar to the general telnet usage, but in short:
|
||||
```
|
||||
./build_oai --ninja -c --gNB --nrUE --build-lib telnetsrv
|
||||
```
|
||||
to build everything including the telnet library. Then, run the nr-softmodem
|
||||
by activating telnet and loading the `o1` module:
|
||||
```
|
||||
./nr-softmodem -O <config> --telnetsrv --telnetsrv.shrmod o1
|
||||
```
|
||||
|
||||
Afterwards, it should be possible to connect via telnet on localhost, port
|
||||
9090. Use `help` to get help on the different command sections, and type e.g.
|
||||
`o1 stats` to get statistics (more information further below):
|
||||
|
||||
```
|
||||
$ telnet 127.0.0.1 9090
|
||||
Trying 127.0.0.1...
|
||||
Connected to 127.0.0.1.
|
||||
Escape character is '^]'.
|
||||
|
||||
softmodem_gnb> help
|
||||
[...]
|
||||
module 4 = o1:
|
||||
o1 stats
|
||||
o1 config ?
|
||||
o1 stop_modem
|
||||
o1 start_modem
|
||||
[...]
|
||||
softmodem_gnb> o1 stats
|
||||
[...]
|
||||
softmodem_gnb> exit
|
||||
Connection closed by foreign host.
|
||||
```
|
||||
|
||||
It also possible to send a command "directly from the command line", by piping
|
||||
the command into netcat:
|
||||
```
|
||||
echo o1 stats | nc -N 127.0.0.1 9090
|
||||
```
|
||||
|
||||
Note that only one telnet client can be connected at a time.
|
||||
|
||||
# Get statistics
|
||||
|
||||
Use the `o1 stats` command. The output is in JSON format:
|
||||
```json
|
||||
{
|
||||
"o1-config": {
|
||||
"BWP": {
|
||||
"dl": [
|
||||
{
|
||||
"bwp3gpp:isInitialBwp": true,
|
||||
"bwp3gpp:numberOfRBs": 106,
|
||||
"bwp3gpp:startRB": 0,
|
||||
"bwp3gpp:subCarrierSpacing": 30
|
||||
}
|
||||
],
|
||||
"ul": [
|
||||
{
|
||||
"bwp3gpp:isInitialBwp": true,
|
||||
"bwp3gpp:numberOfRBs": 106,
|
||||
"bwp3gpp:startRB": 0,
|
||||
"bwp3gpp:subCarrierSpacing": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
"NRCELLDU": {
|
||||
"nrcelldu3gpp:ssbFrequency": 641280,
|
||||
"nrcelldu3gpp:arfcnDL": 640008,
|
||||
"nrcelldu3gpp:bSChannelBwDL": 40,
|
||||
"nrcelldu3gpp:arfcnUL": 640008,
|
||||
"nrcelldu3gpp:bSChannelBwUL": 40,
|
||||
"nrcelldu3gpp:nRPCI": 0,
|
||||
"nrcelldu3gpp:nRTAC": 1,
|
||||
"nrcelldu3gpp:mcc": "208",
|
||||
"nrcelldu3gpp:mnc": "95",
|
||||
"nrcelldu3gpp:sd": 16777215,
|
||||
"nrcelldu3gpp:sst": 1
|
||||
},
|
||||
"device": {
|
||||
"gnbId": 1,
|
||||
"gnbName": "gNB-Eurecom-5GNRBox",
|
||||
"vendor": "OpenAirInterface"
|
||||
}
|
||||
},
|
||||
"O1-Operational": {
|
||||
"frame-type": "tdd",
|
||||
"band-number": 78,
|
||||
"num-ues": 1,
|
||||
"ues": [
|
||||
6876
|
||||
],
|
||||
"load": 9,
|
||||
"ues-thp": [
|
||||
{
|
||||
"rnti": 6876,
|
||||
"dl": 3279,
|
||||
"ul": 2725
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that no actual JSON engine is used, so no actual verification is done; it
|
||||
is for convenience of the consumer. To verify, you can employ `jq`:
|
||||
```
|
||||
echo o1 stats | nc -N 127.0.0.1 9090 | awk '/^{$/, /^}$/' | jq .
|
||||
```
|
||||
(`awk`'s pattern matching makes that only everything between the first `{` and
|
||||
its corresponding `}` is printed).
|
||||
|
||||
There are two sections:
|
||||
1. `.o1-config` show some stats that map directly to the O1 Netconf model. Note
|
||||
that only one MCC/MNC/SD/SST (each) are supported right now. Also, note that
|
||||
as per 3GPP specifications, SD of value `0xffffff` (16777215 in decimal)
|
||||
means "no SD". `bSChannelBwDL/UL` is reported in MHz.
|
||||
2. `.O1-operational` output some statistics that do not map yet to any netconf
|
||||
parameters, but that might be useful nevertheless for a consumer.
|
||||
|
||||
# Write a new configuration
|
||||
|
||||
Use `o1 config` to write a configuration:
|
||||
```
|
||||
echo o1 config nrcelldu3gpp:ssbFrequency 620736 nrcelldu3gpp:arfcnDL 620020 nrcelldu3gpp:bSChannelBwDL 51 bwp3gpp:numberOfRBs 51 bwp3gpp:startRB 0 | nc -N 127.0.0.1 9090
|
||||
```
|
||||
You have to pass the above parameters in exactly this order. The softmodem
|
||||
needs to be stopped; it will pick up the new configuration when starting the
|
||||
softmodem again.
|
||||
|
||||
Note that you cannot switch three-quarter sampling for this as of now.
|
||||
|
||||
For values of the configuration, refer to the next section.
|
||||
|
||||
# Use hardcoded configuration
|
||||
|
||||
Use `o1 bwconfig` to write a hard-coded configuration for 20 or 40 MHz cells:
|
||||
```
|
||||
echo o1 bwconfig 20 | nc -N 127.0.0.1 9090
|
||||
echo o1 bwconfig 40 | nc -N 127.0.0.1 9090
|
||||
```
|
||||
|
||||
The softmodem needs to be stopped; it will pick up the new configuration when
|
||||
starting the softmodem again.
|
||||
|
||||
Use `o1 stats` to see which configurations are set by these commands for the
|
||||
parameters `nrcelldu3gpp:ssbFrequency`, `nrcelldu3gpp:arfcnDL`,
|
||||
`nrcelldu3gpp:arfcnUL`, `nrcelldu3gpp:bSChannelBwDL`,
|
||||
`nrcelldu3gpp:bSChannelBwUL`, and `bwp3gpp:numberOfRBsbwp3gpp:startRB`.
|
||||
Furthermore, for 20MHz, it *disables* three-quarter sampling, whereas it
|
||||
*enables* three-quarter sampling for 40MHz.
|
||||
|
||||
# Restart the softmodem
|
||||
|
||||
Use `o1 stop_modem` to stop the `nr-softmodem`. To restart the softmodem, use
|
||||
`o1 start_modem`:
|
||||
```
|
||||
echo o1 stop_modem | nc -N 127.0.0.1 9090
|
||||
echo o1 start_modem | nc -N 127.0.0.1 9090
|
||||
```
|
||||
|
||||
In fact, stopping terminates all L1 threads and, due to implementation details,
|
||||
the RRC thread. It will be as if the softmodem "freezes", and no periodical
|
||||
output of statistics will occur (the O1 telnet interface will still work,
|
||||
though). Starting again will "defreeze" the softmodem.
|
||||
|
||||
`stop_modem` works reliably at this point. `start_modem` comes with a couple of
|
||||
caveats:
|
||||
* not all memory is freed properly: for instance, the configuration module runs
|
||||
out of memory after a couple of restarts, and will stop everything.
|
||||
* it is advisable to disconnect any UE before stopping. The MAC runs in the
|
||||
same thread as the L1, and since we stop the L1, it is as if the MAC
|
||||
"freezes" in time. When you restart the softmodem, frame and slot numbers
|
||||
might not match with data stored internally at the MAC, and the softmodem
|
||||
might assert. Alse, any UE will be disconnected (USRP: no radio, RFsimulator:
|
||||
TCP socket closed); this in itself is not a problem from a gNB perspective,
|
||||
but of course the UE is not immediately operational after restarting.
|
||||
@@ -3,5 +3,6 @@ The oai embedded telnet server is an optional monitoring and debugging tool. It
|
||||
* [Using the telnet server](telnetusage.md)
|
||||
* [Adding commands to the oai telnet server](telnetaddcmd.md)
|
||||
* [telnet server architecture ](telnetarch.md)
|
||||
* [on the telnet O1 module](telneto1.md)
|
||||
|
||||
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
||||
|
||||
@@ -681,7 +681,6 @@ void run_telnetsrv(void) {
|
||||
}
|
||||
|
||||
if(!readc) {
|
||||
printf ("[TELNETSRV] Telnet Client disconnected.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -727,7 +726,7 @@ void run_telnetsrv(void) {
|
||||
write_history(telnetparams.histfile);
|
||||
clear_history();
|
||||
close(telnetparams.new_socket);
|
||||
printf ("[TELNETSRV] Telnet server waitting for connection...\n");
|
||||
//printf ("[TELNETSRV] Telnet server waitting for connection...\n");
|
||||
}
|
||||
|
||||
close(sock);
|
||||
|
||||
447
common/utils/telnetsrv/telnetsrv_o1.c
Normal file
447
common/utils/telnetsrv/telnetsrv_o1.c
Normal file
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* 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 <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define TELNETSERVERCODE
|
||||
#include "telnetsrv.h"
|
||||
|
||||
#include "openair2/RRC/NR/nr_rrc_defs.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "openair2/RRC/NR/nr_rrc_config.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
#define ERROR_MSG_RET(mSG, aRGS...) do { prnt("FAILURE: " mSG, ##aRGS); return 1; } while (0)
|
||||
|
||||
#define ISINITBWP "bwp3gpp:isInitialBwp"
|
||||
//#define CYCLPREF "bwp3gpp:cyclicPrefix"
|
||||
#define NUMRBS "bwp3gpp:numberOfRBs"
|
||||
#define STARTRB "bwp3gpp:startRB"
|
||||
#define BWPSCS "bwp3gpp:subCarrierSpacing"
|
||||
|
||||
#define SSBFREQ "nrcelldu3gpp:ssbFrequency"
|
||||
#define ARFCNDL "nrcelldu3gpp:arfcnDL"
|
||||
#define BWDL "nrcelldu3gpp:bSChannelBwDL"
|
||||
#define ARFCNUL "nrcelldu3gpp:arfcnUL"
|
||||
#define BWUL "nrcelldu3gpp:bSChannelBwUL"
|
||||
#define PCI "nrcelldu3gpp:nRPCI"
|
||||
#define TAC "nrcelldu3gpp:nRTAC"
|
||||
#define MCC "nrcelldu3gpp:mcc"
|
||||
#define MNC "nrcelldu3gpp:mnc"
|
||||
#define SD "nrcelldu3gpp:sd"
|
||||
#define SST "nrcelldu3gpp:sst"
|
||||
|
||||
typedef struct b {
|
||||
long int dl;
|
||||
long int ul;
|
||||
} b_t;
|
||||
|
||||
static int get_stats(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (buf)
|
||||
ERROR_MSG_RET("no parameter allowed\n");
|
||||
|
||||
const gNB_MAC_INST *mac = RC.nrmac[0];
|
||||
AssertFatal(mac != NULL, "need MAC\n");
|
||||
|
||||
const f1ap_setup_req_t *sr = mac->f1_config.setup_req;
|
||||
const f1ap_served_cell_info_t *cell_info = &sr->cell[0].info;
|
||||
|
||||
const NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
|
||||
const NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||
const NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
||||
frame_type_t frame_type = get_frame_type(*frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
const NR_BWP_t *initialDL = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
const NR_BWP_t *initialUL = &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
|
||||
int scs = initialDL->subcarrierSpacing;
|
||||
AssertFatal(scs == initialUL->subcarrierSpacing, "different SCS for UL/DL not supported!\n");
|
||||
int band = *frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
int nrb = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
AssertFatal(nrb == frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth, "different BW for UL/DL not supported!\n");
|
||||
int bw_index = get_supported_band_index(scs, band, nrb);
|
||||
int bw_mhz = get_supported_bw_mhz(band > 256 ? FR2 : FR1, bw_index);
|
||||
|
||||
int num_ues = 0;
|
||||
UE_iterator((NR_UE_info_t **)mac->UE_info.list, it) {
|
||||
num_ues++;
|
||||
}
|
||||
|
||||
const mac_stats_t *stat = &mac->mac_stats;
|
||||
static mac_stats_t last = {0};
|
||||
int diff_used = stat->used_prb_aggregate - last.used_prb_aggregate;
|
||||
int diff_total = stat->total_prb_aggregate - last.total_prb_aggregate;
|
||||
int load = diff_total > 0 ? 100 * diff_used / diff_total : 0;
|
||||
last = *stat;
|
||||
|
||||
static struct timespec tp_last = {0};
|
||||
struct timespec tp_now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp_now);
|
||||
size_t diff_msec = (tp_now.tv_sec - tp_last.tv_sec) * 1000 + (tp_now.tv_nsec - tp_last.tv_nsec) / 1000000;
|
||||
tp_last = tp_now;
|
||||
|
||||
const int srb_flag = 0;
|
||||
const int rb_id = 1;
|
||||
static b_t last_total[MAX_MOBILES_PER_GNB] = {0};
|
||||
b_t thr[MAX_MOBILES_PER_GNB] = {0};
|
||||
int i = 0;
|
||||
{
|
||||
UE_iterator((NR_UE_info_t **)mac->UE_info.list, it) {
|
||||
nr_rlc_statistics_t rlc = {0};
|
||||
nr_rlc_get_statistics(it->rnti, srb_flag, rb_id, &rlc);
|
||||
// static var last_total: we might have old data, larger than what
|
||||
// reports RLC, leading to a huge number -> cut off to zero
|
||||
if (last_total[i].dl > rlc.txpdu_bytes)
|
||||
last_total[i].dl = rlc.txpdu_bytes;
|
||||
if (last_total[i].ul > rlc.rxpdu_bytes)
|
||||
last_total[i].ul = rlc.rxpdu_bytes;
|
||||
thr[i].dl = (rlc.txpdu_bytes - last_total[i].dl) * 8 / diff_msec;
|
||||
thr[i].ul = (rlc.rxpdu_bytes - last_total[i].ul) * 8 / diff_msec;
|
||||
last_total[i].dl = rlc.txpdu_bytes;
|
||||
last_total[i].ul = rlc.rxpdu_bytes;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
prnt("{\n");
|
||||
prnt(" \"o1-config\": {\n");
|
||||
|
||||
prnt(" \"BWP\": {\n");
|
||||
prnt(" \"dl\": [{\n");
|
||||
prnt(" \"" ISINITBWP "\": true,\n");
|
||||
//prnt(" \"" CYCLPREF "\": %ld,\n", *initialDL->cyclicPrefix);
|
||||
prnt(" \"" NUMRBS "\": %ld,\n", NRRIV2BW(initialDL->locationAndBandwidth, MAX_BWP_SIZE));
|
||||
prnt(" \"" STARTRB "\": %ld,\n", NRRIV2PRBOFFSET(initialDL->locationAndBandwidth, MAX_BWP_SIZE));
|
||||
prnt(" \"" BWPSCS "\": %ld\n", 15 * (1U << scs));
|
||||
prnt(" }],\n");
|
||||
prnt(" \"ul\": [{\n");
|
||||
prnt(" \"" ISINITBWP "\": true,\n");
|
||||
//prnt(" \"" CYCLPREF "\": %ld,\n", *initialUL->cyclicPrefix);
|
||||
prnt(" \"" NUMRBS "\": %ld,\n", NRRIV2BW(initialUL->locationAndBandwidth, MAX_BWP_SIZE));
|
||||
prnt(" \"" STARTRB "\": %ld,\n", NRRIV2PRBOFFSET(initialUL->locationAndBandwidth, MAX_BWP_SIZE));
|
||||
prnt(" \"" BWPSCS "\": %ld\n", 15 * (1U << scs));
|
||||
prnt(" }]\n");
|
||||
prnt(" },\n");
|
||||
|
||||
prnt(" \"NRCELLDU\": {\n");
|
||||
prnt(" \"" SSBFREQ "\": %ld,\n", *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB);
|
||||
prnt(" \"" ARFCNDL "\": %ld,\n", frequencyInfoDL->absoluteFrequencyPointA);
|
||||
prnt(" \"" BWDL "\": %ld,\n", bw_mhz);
|
||||
prnt(" \"" ARFCNUL "\": %ld,\n", frequencyInfoUL->absoluteFrequencyPointA ? *frequencyInfoUL->absoluteFrequencyPointA : frequencyInfoDL->absoluteFrequencyPointA);
|
||||
prnt(" \"" BWUL "\": %ld,\n", bw_mhz);
|
||||
prnt(" \"" PCI "\": %ld,\n", *scc->physCellId);
|
||||
prnt(" \"" TAC "\": %ld,\n", *cell_info->tac);
|
||||
prnt(" \"" MCC "\": \"%03d\",\n", cell_info->plmn.mcc);
|
||||
prnt(" \"" MNC "\": \"%0*d\",\n", cell_info->plmn.mnc_digit_length, cell_info->plmn.mnc);
|
||||
prnt(" \"" SD "\": %d,\n", cell_info->sd);
|
||||
prnt(" \"" SST "\": %d\n", cell_info->sst);
|
||||
prnt(" },\n");
|
||||
prnt(" \"device\": {\n");
|
||||
prnt(" \"gnbId\": %d,\n", sr->gNB_DU_id);
|
||||
prnt(" \"gnbName\": \"%s\",\n", sr->gNB_DU_name);
|
||||
prnt(" \"vendor\": \"OpenAirInterface\"\n");
|
||||
prnt(" }\n");
|
||||
prnt(" },\n");
|
||||
|
||||
prnt(" \"O1-Operational\": {\n");
|
||||
prnt(" \"frame-type\": \"%s\",\n", frame_type == TDD ? "tdd" : "fdd");
|
||||
prnt(" \"band-number\": %ld,\n", band);
|
||||
prnt(" \"num-ues\": %d,\n", num_ues);
|
||||
prnt(" \"ues\": [");
|
||||
{
|
||||
bool first = true;
|
||||
UE_iterator((NR_UE_info_t **)mac->UE_info.list, it) {
|
||||
if (!first) { prnt(", "); }
|
||||
prnt("%d", it->rnti);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
prnt(" ],\n");
|
||||
prnt(" \"load\": %d,\n", load);
|
||||
prnt(" \"ues-thp\": [\n");
|
||||
{
|
||||
bool first = true;
|
||||
int i = 0;
|
||||
UE_iterator((NR_UE_info_t **)mac->UE_info.list, it) {
|
||||
if (!first) { prnt(", "); }
|
||||
prnt(" {\"rnti\": %d, \"dl\": %ld, \"ul\": %ld}\n", it->rnti, thr[i].dl, thr[i].ul);
|
||||
i++;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
prnt(" ]\n");
|
||||
prnt(" }\n");
|
||||
prnt("}\n");
|
||||
prnt("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_long(const char *buf, const char *end, const char *id, long *val)
|
||||
{
|
||||
const char *curr = buf;
|
||||
while (isspace(*curr) && curr < end) // skip leading spaces
|
||||
curr++;
|
||||
int len = strlen(id);
|
||||
if (curr + len >= end)
|
||||
return -1;
|
||||
if (strncmp(curr, id, len) != 0) // check buf has id
|
||||
return -1;
|
||||
curr += len;
|
||||
while (isspace(*curr) && curr < end) // skip middle spaces
|
||||
curr++;
|
||||
if (curr >= end)
|
||||
return -1;
|
||||
int nread = sscanf(curr, "%ld", val);
|
||||
if (nread != 1)
|
||||
return -1;
|
||||
while (isdigit(*curr) && curr < end) // skip all digits read above
|
||||
curr++;
|
||||
if (curr > end)
|
||||
return -1;
|
||||
return curr - buf;
|
||||
}
|
||||
|
||||
bool running = true; // in the beginning, the softmodem is started automatically
|
||||
static int set_config(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (!buf)
|
||||
ERROR_MSG_RET("need param: o1 config param1 val1 [param2 val2 ...]\n");
|
||||
if (running)
|
||||
ERROR_MSG_RET("cannot set parameters while L1 is running\n");
|
||||
const char *end = buf + strlen(buf);
|
||||
|
||||
/* we need to update the following fields to change frequency and/or
|
||||
* bandwidth:
|
||||
* --gNBs.[0].servingCellConfigCommon.[0].absoluteFrequencySSB 620736 -> SSBFREQ
|
||||
* --gNBs.[0].servingCellConfigCommon.[0].dl_absoluteFrequencyPointA 620020 -> ARFCNDL
|
||||
* --gNBs.[0].servingCellConfigCommon.[0].dl_carrierBandwidth 51 -> BWDL
|
||||
* --gNBs.[0].servingCellConfigCommon.[0].initialDLBWPlocationAndBandwidth 13750 -> NUMRBS + STARTRB
|
||||
* --gNBs.[0].servingCellConfigCommon.[0].ul_carrierBandwidth 51 -> BWUL?
|
||||
* --gNBs.[0].servingCellConfigCommon.[0].initialULBWPlocationAndBandwidth 13750 -> ?
|
||||
*/
|
||||
|
||||
int processed = 0;
|
||||
int pos = 0;
|
||||
|
||||
long ssbfreq;
|
||||
processed = read_long(buf + pos, end, SSBFREQ, &ssbfreq);
|
||||
if (processed < 0)
|
||||
ERROR_MSG_RET("could not read " SSBFREQ " at index %d\n", pos + processed);
|
||||
pos += processed;
|
||||
prnt("setting " SSBFREQ ": %ld [len %d]\n", ssbfreq, pos);
|
||||
|
||||
long arfcn;
|
||||
processed = read_long(buf + pos, end, ARFCNDL, &arfcn);
|
||||
if (processed < 0)
|
||||
ERROR_MSG_RET("could not read " ARFCNDL " at index %d\n", pos + processed);
|
||||
pos += processed;
|
||||
prnt("setting " ARFCNDL ": %ld [len %d]\n", arfcn, pos);
|
||||
|
||||
long bwdl;
|
||||
processed = read_long(buf + pos, end, BWDL, &bwdl);
|
||||
if (processed < 0)
|
||||
ERROR_MSG_RET("could not read " BWDL " at index %d\n", pos + processed);
|
||||
pos += processed;
|
||||
prnt("setting " BWDL ": %ld [len %d]\n", bwdl, pos);
|
||||
|
||||
long numrbs;
|
||||
processed = read_long(buf + pos, end, NUMRBS, &numrbs);
|
||||
if (processed < 0)
|
||||
ERROR_MSG_RET("could not read " NUMRBS " at index %d\n", pos + processed);
|
||||
pos += processed;
|
||||
prnt("setting " NUMRBS ": %ld [len %d]\n", numrbs, pos);
|
||||
|
||||
long startrb;
|
||||
processed = read_long(buf + pos, end, STARTRB, &startrb);
|
||||
if (processed < 0)
|
||||
ERROR_MSG_RET("could not read " STARTRB " at index %d\n", pos + processed);
|
||||
pos += processed;
|
||||
prnt("setting " STARTRB ": %ld [len %d]\n", startrb, pos);
|
||||
|
||||
int locationAndBandwidth = PRBalloc_to_locationandbandwidth0(numrbs, startrb, MAX_BWP_SIZE);
|
||||
prnt("inferred locationAndBandwidth: %d\n", locationAndBandwidth);
|
||||
|
||||
/*
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||
NR_ServingCellConfigCommon_t *scc = rrc->carrier.servingcellconfigcommon;
|
||||
NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||
NR_BWP_t *initialDL = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
||||
NR_BWP_t *initialUL = &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
|
||||
//--gNBs.[0].servingCellConfigCommon.[0].absoluteFrequencySSB 620736 -> SSBFREQ
|
||||
*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB = ssbfreq;
|
||||
|
||||
// --gNBs.[0].servingCellConfigCommon.[0].dl_absoluteFrequencyPointA 620020 -> ARFCNDL
|
||||
frequencyInfoDL->absoluteFrequencyPointA = arfcn;
|
||||
AssertFatal(frequencyInfoUL->absoluteFrequencyPointA == NULL, "only handle TDD\n");
|
||||
|
||||
// --gNBs.[0].servingCellConfigCommon.[0].dl_carrierBandwidth 51 -> BWDL
|
||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth = bwdl;
|
||||
|
||||
// --gNBs.[0].servingCellConfigCommon.[0].initialDLBWPlocationAndBandwidth 13750 -> NUMRBS + STARTRB
|
||||
initialDL->locationAndBandwidth = locationAndBandwidth;
|
||||
|
||||
// --gNBs.[0].servingCellConfigCommon.[0].ul_carrierBandwidth 51 -> BWUL?
|
||||
// we assume the same BW as DL
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth = bwdl;
|
||||
|
||||
// --gNBs.[0].servingCellConfigCommon.[0].initialULBWPlocationAndBandwidth 13750 -> ?
|
||||
// we assume same locationAndBandwidth as DL
|
||||
initialUL->locationAndBandwidth = locationAndBandwidth;
|
||||
*/
|
||||
|
||||
prnt("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int8_t threequarter_fs;
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
static int set_bwconfig(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (running)
|
||||
ERROR_MSG_RET("cannot set parameters while L1 is running\n");
|
||||
if (!buf)
|
||||
ERROR_MSG_RET("need param: o1 bwconfig <BW>\n");
|
||||
|
||||
char *end = NULL;
|
||||
if (NULL != (end = strchr(buf, '\n')))
|
||||
*end = 0;
|
||||
if (NULL != (end = strchr(buf, '\r')))
|
||||
*end = 0;
|
||||
|
||||
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
|
||||
NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||
NR_BWP_t *initialDL = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
||||
NR_BWP_t *initialUL = &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
if (strcmp(buf, "40") == 0) {
|
||||
*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB = 641280;
|
||||
frequencyInfoDL->absoluteFrequencyPointA = 640008;
|
||||
AssertFatal(frequencyInfoUL->absoluteFrequencyPointA == NULL, "only handle TDD\n");
|
||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth = 106;
|
||||
initialDL->locationAndBandwidth = 28875;
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth = 106;
|
||||
initialUL->locationAndBandwidth = 28875;
|
||||
threequarter_fs = 1;
|
||||
openair0_cfg[0].threequarter_fs = 1;
|
||||
} else if (strcmp(buf, "20") == 0) {
|
||||
*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB = 641280;
|
||||
frequencyInfoDL->absoluteFrequencyPointA = 640596;
|
||||
AssertFatal(frequencyInfoUL->absoluteFrequencyPointA == NULL, "only handle TDD\n");
|
||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth = 51;
|
||||
initialDL->locationAndBandwidth = 13750;
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth = 51;
|
||||
initialUL->locationAndBandwidth = 13750;
|
||||
threequarter_fs = 0;
|
||||
openair0_cfg[0].threequarter_fs = 0;
|
||||
} else {
|
||||
ERROR_MSG_RET("unhandled option %s\n", buf);
|
||||
}
|
||||
|
||||
free(RC.nrmac[0]->sched_ctrlCommon);
|
||||
RC.nrmac[0]->sched_ctrlCommon = NULL;
|
||||
|
||||
|
||||
free_MIB_NR(mac->common_channels[0].mib);
|
||||
mac->common_channels[0].mib = get_new_MIB_NR(scc);
|
||||
|
||||
// due to outrightly CRAZY memory handling in get_SIB1_NR(), we need to set
|
||||
// some structures to zero to prevent that we shoot ourselves into the foot
|
||||
//struct NR_SIB1 *xyz = rrc->carrier.siblock1->message.choice.c1->choice.systemInformationBlockType1;
|
||||
//xyz->servingCellConfigCommon = NULL;
|
||||
//free_SIB1_NR(rrc->carrier.siblock1);
|
||||
const f1ap_served_cell_info_t *info = &mac->f1_config.setup_req->cell[0].info;
|
||||
/*
|
||||
NR_BCCH_DL_SCH_Message_t *sib1 = get_SIB1_NR(scc, &info->plmn, into->nr_cellid, *info.tac);
|
||||
rrc->carrier.SIB1 = calloc(NR_MAX_SIB_LENGTH / 8, sizeof(*rrc->carrier.SIB1));
|
||||
AssertFatal(rrc->carrier.SIB1 != NULL, "out of memory\n");
|
||||
rrc->carrier.sizeof_SIB1 = encode_SIB1_NR(sib1, rrc->carrier.SIB1, NR_MAX_SIB_LENGTH / 8);
|
||||
rrc->carrier.siblock1 = sib1;
|
||||
*/
|
||||
nr_mac_configure_sib1(mac, &info->plmn, info->nr_cellid, *info->tac);
|
||||
|
||||
//nr_mac_config_scc(mac, scc, &mac->radio_config);
|
||||
|
||||
prnt("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int stop_L1L2(module_id_t gnb_id);
|
||||
static int stop_modem(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (!running)
|
||||
ERROR_MSG_RET("cannot stop, nr-softmodem not running\n");
|
||||
|
||||
/* make UEs out of sync and wait 20ms to ensure no PUCCH is scheduled. After
|
||||
* a restart, the frame/slot numbers will be different, which "confuses" the
|
||||
* scheduler, which has many PUCCH structures filled with expected frame/slot
|
||||
* combinations that won't happen. */
|
||||
const gNB_MAC_INST *mac = RC.nrmac[0];
|
||||
UE_iterator((NR_UE_info_t **)mac->UE_info.list, it) {
|
||||
it->UE_sched_ctrl.rrc_processing_timer = 1000;
|
||||
}
|
||||
usleep(50000);
|
||||
|
||||
stop_L1L2(0);
|
||||
running = false;
|
||||
prnt("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int start_L1L2(module_id_t gnb_id);
|
||||
static int start_modem(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (running)
|
||||
ERROR_MSG_RET("cannot start, nr-softmodem already running\n");
|
||||
start_L1L2(0);
|
||||
running = true;
|
||||
prnt("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static telnetshell_cmddef_t o1cmds[] = {
|
||||
{"stats", "", get_stats},
|
||||
{"config", "[]", set_config},
|
||||
{"bwconfig", "", set_bwconfig},
|
||||
{"stop_modem", "", stop_modem},
|
||||
{"start_modem", "", start_modem},
|
||||
{"", "", NULL},
|
||||
};
|
||||
|
||||
static telnetshell_vardef_t o1vars[] = {
|
||||
{"", 0, 0, NULL}
|
||||
};
|
||||
|
||||
void add_o1_cmds(void) {
|
||||
add_telnetcmd("o1", o1vars, o1cmds);
|
||||
}
|
||||
@@ -66,7 +66,9 @@ RUN apt-get update && \
|
||||
|
||||
WORKDIR /opt/oai-gnb/bin
|
||||
COPY --from=gnb-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/nr-softmodem ./
|
||||
/oai-ran/cmake_targets/ran_build/build/nr-softmodem \
|
||||
./
|
||||
|
||||
COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh
|
||||
|
||||
COPY --from=gnb-build \
|
||||
@@ -79,6 +81,10 @@ COPY --from=gnb-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_bearer.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_enb.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_o1.so \
|
||||
/usr/local/lib/
|
||||
|
||||
# Now we are copying from builder-image the UHD files.
|
||||
|
||||
@@ -149,6 +149,9 @@ f1ap_cudu_inst_t *getCxt(instance_t instanceP)
|
||||
return &fake;
|
||||
}
|
||||
configmodule_interface_t *uniqCfg = NULL;
|
||||
|
||||
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, uint32_t gNB_ue_ngap_id) { };
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/// static configuration for NR at the moment
|
||||
|
||||
@@ -548,6 +548,122 @@ void terminate_task(task_id_t task_id, module_id_t mod_id) {
|
||||
//extern void free_transport(PHY_VARS_gNB *);
|
||||
extern void nr_phy_free_RU(RU_t *);
|
||||
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
int stop_L1L2(module_id_t gnb_id)
|
||||
{
|
||||
LOG_W(GNB_APP, "stopping nr-softmodem\n");
|
||||
oai_exit = 1;
|
||||
|
||||
if (!RC.ru) {
|
||||
LOG_F(GNB_APP, "no RU configured\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* stop trx devices, multiple carrier currently not supported by RU */
|
||||
if (RC.ru[gnb_id]) {
|
||||
AssertFatal(RC.ru[gnb_id]->rfdevice.trx_stop_func != NULL, "cannot call rfdevice.trx_stop_func(), is NULL\n");
|
||||
RC.ru[gnb_id]->rfdevice.trx_stop_func(&RC.ru[gnb_id]->rfdevice);
|
||||
LOG_I(GNB_APP, "turned off RU rfdevice\n");
|
||||
|
||||
/*
|
||||
AssertFatal(RC.ru[gnb_id]->ifdevice.trx_stop_func != NULL, "cannot call ifdevice.trx_stop_func(), is NULL\n");
|
||||
RC.ru[gnb_id]->ifdevice.trx_stop_func(&RC.ru[gnb_id]->ifdevice);
|
||||
LOG_I(GNB_APP, "turned off RU ifdevice\n");
|
||||
*/
|
||||
}
|
||||
|
||||
/* these tasks/layers need to pick up new configuration */
|
||||
if (RC.nb_nr_L1_inst > 0)
|
||||
stop_gNB(RC.nb_nr_L1_inst);
|
||||
|
||||
if (RC.nb_RU > 0)
|
||||
stop_RU(RC.nb_RU);
|
||||
|
||||
/* release memory used by the RU/gNB threads (incomplete), after all
|
||||
* threads have been stopped (they partially use the same memory) */
|
||||
for (int inst = 0; inst < RC.nb_RU; inst++) {
|
||||
nr_phy_free_RU(RC.ru[inst]);
|
||||
}
|
||||
|
||||
for (int inst = 0; inst < RC.nb_nr_L1_inst; inst++) {
|
||||
phy_free_nr_gNB(RC.gNB[inst]);
|
||||
}
|
||||
oai_exit = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern f1ap_tdd_info_t read_tdd_config(const NR_ServingCellConfigCommon_t *scc);
|
||||
extern f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1);
|
||||
/*
|
||||
* Restart the nr-softmodem after it has been soft-stopped with stop_L1L2()
|
||||
*/
|
||||
int start_L1L2(module_id_t gnb_id)
|
||||
{
|
||||
//RU_t *ru = RC.ru[gnb_id];
|
||||
//MessageDef *msg_p = NULL;
|
||||
LOG_W(GNB_APP, "restarting nr-softmodem\n");
|
||||
/* block threads */
|
||||
sync_var = -1;
|
||||
RC.gNB[gnb_id]->configured = 0;
|
||||
extern void init_sched_response(void);
|
||||
init_sched_response();
|
||||
/*
|
||||
RC.ru_mask |= (1 << ru->idx);
|
||||
set_function_spec_param(RC.ru[gnb_id]);
|
||||
LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
|
||||
*/
|
||||
// No more rrc thread, as many race conditions are hidden behind
|
||||
|
||||
//int rc = itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL);
|
||||
//AssertFatal(rc == 0, "could not create RRC task\n");
|
||||
/* pass a reconfiguration request which will configure everything down to
|
||||
* RC.eNB[i][j]->frame_parms, too */
|
||||
/*
|
||||
msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ);
|
||||
NRRRC_CONFIGURATION_REQ(msg_p) = RC.nrrrc[gnb_id]->configuration;
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg_p);
|
||||
*/
|
||||
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
|
||||
nr_mac_config_scc(mac, scc, &mac->radio_config);
|
||||
|
||||
NR_BCCH_BCH_Message_t *mib = mac->common_channels[0].mib;
|
||||
const NR_BCCH_DL_SCH_Message_t *sib1 = mac->common_channels[0].sib1;
|
||||
|
||||
/* update existing config in F1 Setup request structures */
|
||||
f1ap_setup_req_t *sr = mac->f1_config.setup_req;
|
||||
DevAssert(sr->num_cells_available == 1);
|
||||
f1ap_served_cell_info_t *info = &sr->cell[0].info;
|
||||
DevAssert(info->mode == F1AP_MODE_TDD);
|
||||
DevAssert(scc->tdd_UL_DL_ConfigurationCommon != NULL);
|
||||
info->tdd = read_tdd_config(scc); /* updates radio config */
|
||||
|
||||
/* send gNB-DU configuration update to RRC */
|
||||
f1ap_gnb_du_configuration_update_t update = {
|
||||
.transaction_id = 1,
|
||||
.num_cells_to_modify = 1,
|
||||
};
|
||||
update.cell_to_modify[0].old_nr_cellid = info->nr_cellid;
|
||||
update.cell_to_modify[0].info = *info;
|
||||
update.cell_to_modify[0].sys_info = get_sys_info(mib, sib1);
|
||||
mac->mac_rrc.gnb_du_configuration_update(&update);
|
||||
|
||||
//sleep(2);
|
||||
|
||||
init_NR_RU(config_get_if(), NULL);
|
||||
|
||||
start_NR_RU();
|
||||
wait_RUs();
|
||||
init_eNB_afterRU();
|
||||
printf("Sending sync to all threads\n");
|
||||
pthread_mutex_lock(&sync_mutex);
|
||||
sync_var=0;
|
||||
pthread_cond_broadcast(&sync_cond);
|
||||
pthread_mutex_unlock(&sync_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wait_nfapi_init(char *thread_name) {
|
||||
printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name);
|
||||
pthread_mutex_lock( &nfapi_sync_mutex );
|
||||
|
||||
@@ -168,6 +168,9 @@ nr_bler_struct nr_bler_data[NR_NUM_MCS];
|
||||
|
||||
static void init_bler_table(char*);
|
||||
|
||||
// to be removed
|
||||
void nr_mac_trigger_ul_failure(int rnti) { abort(); }
|
||||
|
||||
/*---------------------BMC: timespec helpers -----------------------------*/
|
||||
|
||||
struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
|
||||
253
gnb_20.conf
Normal file
253
gnb_20.conf
Normal file
@@ -0,0 +1,253 @@
|
||||
Active_gNBs = ( "gNB-DU-in-docker");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "gNB-DU-in-docker";
|
||||
|
||||
// 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:
|
||||
|
||||
#min_rxtxtime = 6;
|
||||
force_256qam_off = 0;
|
||||
|
||||
do_CSIRS = 0;
|
||||
do_SRS = 0;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3300.30 MHz + (19 PRBs + 10 SCs)@30kHz SCS (GSCN: 7715)
|
||||
absoluteFrequencySSB = 641280; #620736;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3300.30 MHz
|
||||
dl_absoluteFrequencyPointA = 640596; #620052;
|
||||
#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 = 78;
|
||||
#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;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#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;
|
||||
#oneHalf (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_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
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.70.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "16.1.1.2";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "16.1.1.2";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 230; # 200; after test in lab
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 1;
|
||||
ul_max_mcs = 16;
|
||||
min_grant_prb = 20;
|
||||
}
|
||||
);
|
||||
|
||||
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 = 6; # 8; after test in lab
|
||||
att_rx = 6; # 8; after test in lab
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 115; #120;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
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 ="info";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
267
gnb_40.conf
Normal file
267
gnb_40.conf
Normal file
@@ -0,0 +1,267 @@
|
||||
Active_gNBs = ( "gNB-DU-in-docker");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "gNB-DU-in-docker";
|
||||
|
||||
// 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:
|
||||
|
||||
#min_rxtxtime = 6;
|
||||
force_256qam_off = 0;
|
||||
|
||||
do_CSIRS = 0;
|
||||
do_SRS = 0;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
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 = 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;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#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;
|
||||
#oneHalf (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_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
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.70.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "16.1.1.2";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "16.1.1.2";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
e2_agent = {
|
||||
#address = "10.0.0.4";
|
||||
address = "172.23.100.25";
|
||||
sm_dir = "/usr/local/lib/flexric/"
|
||||
}
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 230; # 200; after test in lab
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 1;
|
||||
ul_max_mcs = 16;
|
||||
min_grant_prb = 20;
|
||||
}
|
||||
);
|
||||
|
||||
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 = 6; # 8; after test in lab
|
||||
att_rx = 6; # 8; after test in lab
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 115;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
|
||||
rfsimulator :
|
||||
{
|
||||
serveraddr = "server";
|
||||
serverport = "4043";
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs";
|
||||
};
|
||||
|
||||
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 ="info";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
@@ -550,11 +550,6 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config)
|
||||
nr_init_frame_parms(gNB_config, fp);
|
||||
|
||||
|
||||
if (RC.gNB[Mod_id]->configured == 1) {
|
||||
LOG_E(PHY,"Already gNB already configured, do nothing\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fd_occasion = 0;
|
||||
nfapi_nr_prach_config_t *prach_config = &gNB_config->prach_config;
|
||||
short_sequence = prach_config->prach_sequence_length.value;
|
||||
|
||||
@@ -217,4 +217,8 @@ void nr_phy_free_RU(RU_t *ru)
|
||||
}
|
||||
}
|
||||
free_and_zero(ru->common.sync_corr);
|
||||
|
||||
PHY_VARS_gNB *gNB0= ru->gNB_list[0];
|
||||
gNB0->num_RU--;
|
||||
DevAssert(gNB0->num_RU >= 0);
|
||||
}
|
||||
|
||||
@@ -27,11 +27,14 @@ MESSAGE_DEF(F1AP_DU_REGISTER_REQ, MESSAGE_PRIORITY_MED, f1ap_du_register_req_t,
|
||||
MESSAGE_DEF(F1AP_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_setup_req_t , f1ap_setup_req)
|
||||
MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_acknowledge_t , f1ap_gnb_cu_configuration_update_acknowledge)
|
||||
MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_failure_t , f1ap_gnb_cu_configuration_update_failure)
|
||||
MESSAGE_DEF(F1AP_GNB_DU_CONFIGURATION_UPDATE, MESSAGE_PRIORITY_MED, f1ap_gnb_du_configuration_update_t, f1ap_gnb_du_configuration_update)
|
||||
|
||||
/* F1AP -> eNB_DU or eNB_CU_RRC -> F1AP application layer messages */
|
||||
MESSAGE_DEF(F1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, f1ap_setup_resp_t , f1ap_setup_resp)
|
||||
MESSAGE_DEF(F1AP_SETUP_FAILURE , MESSAGE_PRIORITY_MED, f1ap_setup_failure_t , f1ap_setup_failure)
|
||||
MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_t , f1ap_gnb_cu_configuration_update)
|
||||
MESSAGE_DEF(F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE , MESSAGE_PRIORITY_MED, f1ap_gnb_du_configuration_update_acknowledge_t, f1ap_gnb_du_configuration_update_acknowledge)
|
||||
MESSAGE_DEF(F1AP_GNB_DU_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, f1ap_gnb_du_configuration_update_failure_t, f1ap_gnb_du_configuration_update_failure)
|
||||
|
||||
/* F1AP -> RRC to inform about lost connection */
|
||||
MESSAGE_DEF(F1AP_LOST_CONNECTION, MESSAGE_PRIORITY_MED, f1ap_lost_connection_t, f1ap_lost_connection)
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
#define F1AP_GNB_CU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update
|
||||
#define F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_acknowledge
|
||||
#define F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_failure
|
||||
#define F1AP_GNB_DU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update
|
||||
#define F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update_acknowledge
|
||||
#define F1AP_GNB_DU_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update_failure
|
||||
|
||||
#define F1AP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_failure
|
||||
|
||||
#define F1AP_LOST_CONNECTION(mSGpTR) (mSGpTR)->ittiMsg.f1ap_lost_connection
|
||||
@@ -127,7 +131,7 @@ typedef struct f1ap_served_cell_info_t {
|
||||
// Number of slide support items (max 16, could be increased to as much as 1024)
|
||||
uint16_t num_ssi;
|
||||
uint8_t sst;
|
||||
uint8_t sd;
|
||||
uint32_t sd;
|
||||
|
||||
f1ap_mode_t mode;
|
||||
union {
|
||||
@@ -246,6 +250,58 @@ typedef struct f1ap_gnb_cu_configuration_update_failure_s {
|
||||
uint16_t criticality_diagnostics;
|
||||
} f1ap_gnb_cu_configuration_update_failure_t;
|
||||
|
||||
/*DU configuration messages*/
|
||||
typedef struct f1ap_gnb_du_configuration_update_s {
|
||||
/*TODO UPDATE TO SUPPORT DU CONFIG*/
|
||||
|
||||
/* Transaction ID */
|
||||
uint64_t transaction_id;
|
||||
/// int cells_to_add
|
||||
uint16_t num_cells_to_add;
|
||||
struct {
|
||||
f1ap_served_cell_info_t info;
|
||||
f1ap_gnb_du_system_info_t *sys_info;
|
||||
} cell_to_add[F1AP_MAX_NB_CELLS];
|
||||
|
||||
/// int cells_to_modify
|
||||
uint16_t num_cells_to_modify;
|
||||
struct {
|
||||
f1ap_plmn_t old_plmn;
|
||||
uint64_t old_nr_cellid; // NR Global Cell Id
|
||||
f1ap_served_cell_info_t info;
|
||||
f1ap_gnb_du_system_info_t *sys_info;
|
||||
} cell_to_modify[F1AP_MAX_NB_CELLS];
|
||||
|
||||
/// int cells_to_delete
|
||||
uint16_t num_cells_to_delete;
|
||||
struct {
|
||||
// NR CGI
|
||||
f1ap_plmn_t plmn;
|
||||
uint64_t nr_cellid; // NR Global Cell Id
|
||||
} cell_to_delete[F1AP_MAX_NB_CELLS];
|
||||
|
||||
/// string holding gNB_CU_name
|
||||
uint64_t *gNB_DU_ID;
|
||||
} f1ap_gnb_du_configuration_update_t;
|
||||
|
||||
typedef struct f1ap_gnb_du_configuration_update_acknowledge_s {
|
||||
/// ulong transaction id
|
||||
uint64_t transaction_id;
|
||||
/// string holding gNB_CU_name
|
||||
char *gNB_CU_name;
|
||||
/// number of DU cells to activate
|
||||
uint16_t num_cells_to_activate; //0< num_cells_to_activate <= 512;
|
||||
served_cells_to_activate_t cells_to_activate[F1AP_MAX_NB_CELLS];
|
||||
} f1ap_gnb_du_configuration_update_acknowledge_t;
|
||||
|
||||
typedef struct f1ap_gnb_du_configuration_update_failure_s {
|
||||
/*TODO UPDATE TO SUPPORT DU CONFIG*/
|
||||
uint16_t cause;
|
||||
uint16_t time_to_wait;
|
||||
uint16_t criticality_diagnostics;
|
||||
} f1ap_gnb_du_configuration_update_failure_t;
|
||||
|
||||
|
||||
typedef struct f1ap_dl_rrc_message_s {
|
||||
|
||||
uint32_t gNB_CU_ue_id;
|
||||
|
||||
@@ -412,6 +412,8 @@ typedef struct NRRrcConfigurationReq_s {
|
||||
uint16_t mnc[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t num_plmn;
|
||||
int sd;
|
||||
int sst;
|
||||
|
||||
bool um_on_default_drb;
|
||||
bool enable_sdap;
|
||||
|
||||
@@ -431,17 +431,337 @@ int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *
|
||||
|
||||
int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
LOG_D(F1AP, "CU_handle_gNB_DU_CONFIGURATION_UPDATE\n");
|
||||
F1AP_GNBDUConfigurationUpdate_t *container;
|
||||
F1AP_GNBDUConfigurationUpdateIEs_t *ie;
|
||||
int i = 0;
|
||||
DevAssert(pdu != NULL);
|
||||
container = &pdu->choice.initiatingMessage->value.choice.GNBDUConfigurationUpdate;
|
||||
|
||||
/* gNB DU Configuration Update == Non UE-related procedure -> stream 0 */
|
||||
if (stream != 0) {
|
||||
LOG_W(F1AP, "[SCTP %d] Received f1 setup request on stream != 0 (%d)\n",
|
||||
assoc_id, stream);
|
||||
}
|
||||
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE);
|
||||
message_p->ittiMsgHeader.originInstance = assoc_id;
|
||||
f1ap_gnb_du_configuration_update_t *req = &F1AP_GNB_DU_CONFIGURATION_UPDATE(message_p);
|
||||
|
||||
/* 3GPP TS 38.473 Transaction ID*/
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_TransactionID, true);
|
||||
req->transaction_id = ie->value.choice.TransactionID;
|
||||
LOG_D(F1AP, "req->transaction_id %lu \n", req->transaction_id);
|
||||
|
||||
/* 3GPP TS 38.473 Served Cells To Add List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List, false);
|
||||
|
||||
if(ie!=NULL){
|
||||
req->num_cells_to_add = ie->value.choice.Served_Cells_To_Add_List.list.count;
|
||||
LOG_D(F1AP, "req->num_cells_to_add %d \n", req->num_cells_to_add);
|
||||
|
||||
for (i=0; i<req->num_cells_to_add; i++) {
|
||||
F1AP_Served_Cells_To_Add_Item_t *served_cells_item = &((F1AP_Served_Cells_To_Add_ItemIEs_t *)
|
||||
ie->value.choice.Served_Cells_To_Add_List.list.array[i])->
|
||||
value.choice.Served_Cells_To_Add_Item;
|
||||
F1AP_Served_Cell_Information_t *servedCellInformation= &served_cells_item->served_Cell_Information;
|
||||
/* tac */
|
||||
if (servedCellInformation->fiveGS_TAC) {
|
||||
req->cell_to_add[i].info.tac = malloc(sizeof(*req->cell_to_add[i].info.tac));
|
||||
AssertFatal(req->cell_to_add[i].info.tac != NULL, "out of memory\n");
|
||||
OCTET_STRING_TO_INT24(servedCellInformation->fiveGS_TAC, *req->cell_to_add[i].info.tac);
|
||||
LOG_D(F1AP, "req->tac[%d] %d \n", i, *req->cell_to_add[i].info.tac);
|
||||
}
|
||||
|
||||
/* - nRCGI */
|
||||
TBCD_TO_MCC_MNC(&(servedCellInformation->nRCGI.pLMN_Identity),
|
||||
req->cell_to_add[i].info.plmn.mcc,
|
||||
req->cell_to_add[i].info.plmn.mnc,
|
||||
req->cell_to_add[i].info.plmn.mnc_digit_length);
|
||||
// NR cellID
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&servedCellInformation->nRCGI.nRCellIdentity,
|
||||
req->cell_to_add[i].info.nr_cellid);
|
||||
LOG_D(F1AP, "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id,
|
||||
req->cell_to_add[i].info.plmn.mcc,
|
||||
req->cell_to_add[i].info.plmn.mnc,
|
||||
(long long unsigned int)req->cell_to_add[i].info.nr_cellid);
|
||||
|
||||
/* - nRPCI */
|
||||
req->cell_to_add[i].info.nr_pci = servedCellInformation->nRPCI;
|
||||
LOG_D(F1AP, "req->nr_pci[%d] %d \n", i, req->cell_to_add[i].info.nr_pci);
|
||||
|
||||
// FDD Cells
|
||||
if (servedCellInformation->nR_Mode_Info.present==F1AP_NR_Mode_Info_PR_fDD) {
|
||||
req->cell_to_add[i].info.mode = F1AP_MODE_FDD;
|
||||
f1ap_fdd_info_t *FDDs = &req->cell_to_add[i].info.fdd;
|
||||
F1AP_FDD_Info_t * fDD_Info=servedCellInformation->nR_Mode_Info.choice.fDD;
|
||||
FDDs->ul_freqinfo.arfcn = fDD_Info->uL_NRFreqInfo.nRARFCN;
|
||||
AssertFatal(fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n");
|
||||
for (int f=0; f < fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count; f++) {
|
||||
F1AP_FreqBandNrItem_t * FreqItem=fDD_Info->uL_NRFreqInfo.freqBandListNr.list.array[f];
|
||||
FDDs->ul_freqinfo.band = FreqItem->freqBandIndicatorNr;
|
||||
AssertFatal(FreqItem->supportedSULBandList.list.count == 0, "cannot handle SUL bands!\n");
|
||||
}
|
||||
FDDs->dl_freqinfo.arfcn = fDD_Info->dL_NRFreqInfo.nRARFCN;
|
||||
int dlBands=fDD_Info->dL_NRFreqInfo.freqBandListNr.list.count;
|
||||
AssertFatal(dlBands == 0, "cannot handled more than one frequency band\n");
|
||||
for (int dlB=0; dlB < dlBands; dlB++) {
|
||||
F1AP_FreqBandNrItem_t * FreqItem=fDD_Info->dL_NRFreqInfo.freqBandListNr.list.array[dlB];
|
||||
FDDs->dl_freqinfo.band = FreqItem->freqBandIndicatorNr;
|
||||
int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count;
|
||||
AssertFatal(num_available_supported_SULBands == 0, "cannot handle SUL bands!\n");
|
||||
}
|
||||
FDDs->ul_tbw.scs = fDD_Info->uL_Transmission_Bandwidth.nRSCS;
|
||||
FDDs->ul_tbw.nrb = nrb_lut[fDD_Info->uL_Transmission_Bandwidth.nRNRB];
|
||||
FDDs->dl_tbw.scs = fDD_Info->dL_Transmission_Bandwidth.nRSCS;
|
||||
FDDs->dl_tbw.nrb = nrb_lut[fDD_Info->dL_Transmission_Bandwidth.nRNRB];
|
||||
} else if (servedCellInformation->nR_Mode_Info.present==F1AP_NR_Mode_Info_PR_tDD) {
|
||||
req->cell_to_add[i].info.mode = F1AP_MODE_TDD;
|
||||
f1ap_tdd_info_t *TDDs = &req->cell_to_add[i].info.tdd;
|
||||
F1AP_TDD_Info_t *tDD_Info = servedCellInformation->nR_Mode_Info.choice.tDD;
|
||||
TDDs->freqinfo.arfcn = tDD_Info->nRFreqInfo.nRARFCN;
|
||||
AssertFatal(tDD_Info->nRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n");
|
||||
for (int f=0; f < tDD_Info->nRFreqInfo.freqBandListNr.list.count; f++) {
|
||||
struct F1AP_FreqBandNrItem * FreqItem=tDD_Info->nRFreqInfo.freqBandListNr.list.array[f];
|
||||
TDDs->freqinfo.band = FreqItem->freqBandIndicatorNr;
|
||||
int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count;
|
||||
AssertFatal(num_available_supported_SULBands == 0, "cannot hanlde SUL bands!\n");
|
||||
}
|
||||
TDDs->tbw.scs = tDD_Info->transmission_Bandwidth.nRSCS;
|
||||
TDDs->tbw.nrb = nrb_lut[tDD_Info->transmission_Bandwidth.nRNRB];
|
||||
} else {
|
||||
AssertFatal(false, "unknown NR Mode info %d\n", servedCellInformation->nR_Mode_Info.present);
|
||||
}
|
||||
|
||||
struct F1AP_GNB_DU_System_Information * DUsi=served_cells_item->gNB_DU_System_Information;
|
||||
// System Information
|
||||
req->cell_to_add[i].sys_info = calloc(1, sizeof(*req->cell_to_add[i].sys_info));
|
||||
AssertFatal(req->cell_to_add[i].sys_info != NULL, "out of memory\n");
|
||||
f1ap_gnb_du_system_info_t *sys_info = req->cell_to_add[i].sys_info;
|
||||
/* mib */
|
||||
sys_info->mib = calloc(DUsi->mIB_message.size, sizeof(char));
|
||||
memcpy(sys_info->mib, DUsi->mIB_message.buf, DUsi->mIB_message.size);
|
||||
sys_info->mib_length = DUsi->mIB_message.size;
|
||||
/* sib1 */
|
||||
sys_info->sib1 = calloc(DUsi->sIB1_message.size, sizeof(char));
|
||||
memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size);
|
||||
sys_info->sib1_length = DUsi->sIB1_message.size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
req->num_cells_to_add = 0;
|
||||
}
|
||||
/* 3GPP TS 38.473 Served Cells To Modify List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List, false);
|
||||
|
||||
if(ie){
|
||||
req->num_cells_to_modify = ie->value.choice.Served_Cells_To_Modify_List.list.count;
|
||||
LOG_D(F1AP, "req->num_cells_to_modify %d \n", req->num_cells_to_modify);
|
||||
|
||||
for (i=0; i<req->num_cells_to_modify; i++) {
|
||||
F1AP_Served_Cells_To_Modify_Item_t *served_cells_item = &((F1AP_Served_Cells_To_Modify_ItemIEs_t *)
|
||||
ie->value.choice.Served_Cells_To_Modify_List.list.array[i])->
|
||||
value.choice.Served_Cells_To_Modify_Item;
|
||||
|
||||
/* OLD NRCGI */
|
||||
TBCD_TO_MCC_MNC(&(served_cells_item->oldNRCGI.pLMN_Identity),
|
||||
req->cell_to_modify[i].old_plmn.mcc,
|
||||
req->cell_to_modify[i].old_plmn.mnc,
|
||||
req->cell_to_modify[i].old_plmn.mnc_digit_length);
|
||||
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&served_cells_item->oldNRCGI.nRCellIdentity,
|
||||
req->cell_to_modify[i].old_nr_cellid);
|
||||
|
||||
|
||||
F1AP_Served_Cell_Information_t *servedCellInformation= &served_cells_item->served_Cell_Information;
|
||||
/* SERVED CELL INFORMATION*/
|
||||
/* tac */
|
||||
if (servedCellInformation->fiveGS_TAC) {
|
||||
req->cell_to_modify[i].info.tac = malloc(sizeof(*req->cell_to_modify[i].info.tac));
|
||||
AssertFatal(req->cell_to_modify[i].info.tac != NULL, "out of memory\n");
|
||||
OCTET_STRING_TO_INT16(servedCellInformation->fiveGS_TAC, *req->cell_to_modify[i].info.tac);
|
||||
LOG_D(F1AP, "req->tac[%d] %d \n", i, *req->cell_to_modify[i].info.tac);
|
||||
}
|
||||
|
||||
/* - nRCGI */
|
||||
TBCD_TO_MCC_MNC(&(servedCellInformation->nRCGI.pLMN_Identity),
|
||||
req->cell_to_modify[i].info.plmn.mcc,
|
||||
req->cell_to_modify[i].info.plmn.mnc,
|
||||
req->cell_to_modify[i].info.plmn.mnc_digit_length);
|
||||
// NR cellID
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&servedCellInformation->nRCGI.nRCellIdentity,
|
||||
req->cell_to_modify[i].info.nr_cellid);
|
||||
LOG_D(F1AP, "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id,
|
||||
req->cell_to_modify[i].info.plmn.mcc,
|
||||
req->cell_to_modify[i].info.plmn.mnc,
|
||||
(long long unsigned int)req->cell_to_modify[i].info.nr_cellid);
|
||||
|
||||
/* - nRPCI */
|
||||
req->cell_to_modify[i].info.nr_pci = servedCellInformation->nRPCI;
|
||||
LOG_D(F1AP, "req->nr_pci[%d] %d \n", i, req->cell_to_modify[i].info.nr_pci);
|
||||
|
||||
// FDD Cells
|
||||
if (servedCellInformation->nR_Mode_Info.present==F1AP_NR_Mode_Info_PR_fDD) {
|
||||
req->cell_to_modify[i].info.mode = F1AP_MODE_FDD;
|
||||
f1ap_fdd_info_t *FDDs = &req->cell_to_modify[i].info.fdd;
|
||||
F1AP_FDD_Info_t * fDD_Info=servedCellInformation->nR_Mode_Info.choice.fDD;
|
||||
FDDs->ul_freqinfo.arfcn = fDD_Info->uL_NRFreqInfo.nRARFCN;
|
||||
AssertFatal(fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n");
|
||||
for (int f=0; f < fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count; f++) {
|
||||
F1AP_FreqBandNrItem_t * FreqItem=fDD_Info->uL_NRFreqInfo.freqBandListNr.list.array[f];
|
||||
FDDs->ul_freqinfo.band = FreqItem->freqBandIndicatorNr;
|
||||
AssertFatal(FreqItem->supportedSULBandList.list.count == 0, "cannot handle SUL bands!\n");
|
||||
}
|
||||
FDDs->dl_freqinfo.arfcn = fDD_Info->dL_NRFreqInfo.nRARFCN;
|
||||
int dlBands=fDD_Info->dL_NRFreqInfo.freqBandListNr.list.count;
|
||||
AssertFatal(dlBands == 0, "cannot handled more than one frequency band\n");
|
||||
for (int dlB=0; dlB < dlBands; dlB++) {
|
||||
F1AP_FreqBandNrItem_t * FreqItem=fDD_Info->dL_NRFreqInfo.freqBandListNr.list.array[dlB];
|
||||
FDDs->dl_freqinfo.band = FreqItem->freqBandIndicatorNr;
|
||||
int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count;
|
||||
AssertFatal(num_available_supported_SULBands == 0, "cannot handle SUL bands!\n");
|
||||
}
|
||||
FDDs->ul_tbw.scs = fDD_Info->uL_Transmission_Bandwidth.nRSCS;
|
||||
FDDs->ul_tbw.nrb = nrb_lut[fDD_Info->uL_Transmission_Bandwidth.nRNRB];
|
||||
FDDs->dl_tbw.scs = fDD_Info->dL_Transmission_Bandwidth.nRSCS;
|
||||
FDDs->dl_tbw.nrb = nrb_lut[fDD_Info->dL_Transmission_Bandwidth.nRNRB];
|
||||
} else if (servedCellInformation->nR_Mode_Info.present==F1AP_NR_Mode_Info_PR_tDD) {
|
||||
req->cell_to_modify[i].info.mode = F1AP_MODE_TDD;
|
||||
f1ap_tdd_info_t *TDDs = &req->cell_to_modify[i].info.tdd;
|
||||
F1AP_TDD_Info_t *tDD_Info = servedCellInformation->nR_Mode_Info.choice.tDD;
|
||||
TDDs->freqinfo.arfcn = tDD_Info->nRFreqInfo.nRARFCN;
|
||||
AssertFatal(tDD_Info->nRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n");
|
||||
for (int f=0; f < tDD_Info->nRFreqInfo.freqBandListNr.list.count; f++) {
|
||||
struct F1AP_FreqBandNrItem * FreqItem=tDD_Info->nRFreqInfo.freqBandListNr.list.array[f];
|
||||
TDDs->freqinfo.band = FreqItem->freqBandIndicatorNr;
|
||||
int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count;
|
||||
AssertFatal(num_available_supported_SULBands == 0, "cannot hanlde SUL bands!\n");
|
||||
}
|
||||
TDDs->tbw.scs = tDD_Info->transmission_Bandwidth.nRSCS;
|
||||
TDDs->tbw.nrb = nrb_lut[tDD_Info->transmission_Bandwidth.nRNRB];
|
||||
} else {
|
||||
AssertFatal(false, "unknown NR Mode info %d\n", servedCellInformation->nR_Mode_Info.present);
|
||||
}
|
||||
//TODO: Measurement Config
|
||||
|
||||
|
||||
|
||||
/*gNB DU SYSTEM INFORMATION */
|
||||
struct F1AP_GNB_DU_System_Information * DUsi=served_cells_item->gNB_DU_System_Information;
|
||||
if(DUsi!=NULL){
|
||||
// System Information
|
||||
req->cell_to_modify[i].sys_info = calloc(1, sizeof(*req->cell_to_modify[i].sys_info));
|
||||
AssertFatal(req->cell_to_modify[i].sys_info != NULL, "out of memory\n");
|
||||
f1ap_gnb_du_system_info_t *sys_info = req->cell_to_modify[i].sys_info;
|
||||
/* mib */
|
||||
sys_info->mib = calloc(DUsi->mIB_message.size, sizeof(char));
|
||||
AssertFatal(req->cell_to_modify[i].sys_info->mib != NULL, "out of memory\n");
|
||||
memcpy(sys_info->mib, DUsi->mIB_message.buf, DUsi->mIB_message.size);
|
||||
sys_info->mib_length = DUsi->mIB_message.size;
|
||||
|
||||
/* sib1 */
|
||||
sys_info->sib1 = calloc(DUsi->sIB1_message.size, sizeof(char));
|
||||
AssertFatal(req->cell_to_modify[i].sys_info->sib1 != NULL, "out of memory\n");
|
||||
memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size);
|
||||
sys_info->sib1_length = DUsi->sIB1_message.size;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
req->num_cells_to_modify = 0;
|
||||
}
|
||||
|
||||
/* 3GPP TS 38.473 Served Cells To Delete List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List, false);
|
||||
if(ie){
|
||||
req->num_cells_to_delete = ie->value.choice.Served_Cells_To_Delete_List.list.count;
|
||||
LOG_D(F1AP, "req->num_cells_to_delete %d \n", req->num_cells_to_delete);
|
||||
|
||||
for (i=0; i<req->num_cells_to_delete; i++) {
|
||||
F1AP_Served_Cells_To_Delete_Item_t *served_cells_item = &((F1AP_Served_Cells_To_Delete_ItemIEs_t *)
|
||||
ie->value.choice.Served_Cells_To_Delete_List.list.array[i])->
|
||||
value.choice.Served_Cells_To_Delete_Item;
|
||||
/* - Old nRCGI */
|
||||
TBCD_TO_MCC_MNC(&(served_cells_item->oldNRCGI.pLMN_Identity),
|
||||
req->cell_to_delete[i].plmn.mcc,
|
||||
req->cell_to_delete[i].plmn.mnc,
|
||||
req->cell_to_delete[i].plmn.mnc_digit_length);
|
||||
// NR cellID
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&served_cells_item->oldNRCGI.nRCellIdentity,
|
||||
req->cell_to_delete[i].nr_cellid);
|
||||
LOG_D(F1AP, "[SCTP %d] Received nRCGI to delete: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id,
|
||||
req->cell_to_delete[i].plmn.mcc,
|
||||
req->cell_to_delete[i].plmn.mnc,
|
||||
(long long unsigned int)req->cell_to_delete[i].nr_cellid);
|
||||
}
|
||||
} else {
|
||||
req->num_cells_to_delete = 0;
|
||||
}
|
||||
|
||||
/* 3GPP TS 38.473 Cells Status List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cells_Status_List, false);
|
||||
|
||||
/* 3GPP TS 38.473 Dedicated SI Delivery Needed UE List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Dedicated_SIDelivery_NeededUE_List, false);
|
||||
|
||||
/* 3GPP TS 38.473 gNB-DU ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_ID, false);
|
||||
if(ie!=NULL)
|
||||
asn_INTEGER2ulong(&ie->value.choice.GNB_DU_ID,req->gNB_DU_ID);
|
||||
|
||||
/* 3GPP TS 38.473 gNB-DU TNL Association To Remove List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_GNB_DU_TNL_Association_To_Remove_List, false);
|
||||
|
||||
|
||||
LOG_D(F1AP, "Sending F1AP_GNB_DU_CONFIGURATION_UPDATE ITTI message \n");
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id,
|
||||
F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure) {
|
||||
f1ap_gnb_du_configuration_update_failure_t *GNBDUConfigurationUpdateFailure) {
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id,
|
||||
F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge) {
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t *GNBDUConfigurationUpdateAcknowledge) {
|
||||
F1AP_F1AP_PDU_t pdu = {};
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
|
||||
|
||||
/* Create */
|
||||
/* 0. Message */
|
||||
|
||||
pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
|
||||
asn1cCalloc(pdu.choice.successfulOutcome, succOut);
|
||||
succOut->procedureCode = F1AP_ProcedureCode_id_gNBDUConfigurationUpdate;
|
||||
succOut->criticality = F1AP_Criticality_reject;
|
||||
succOut->value.present = F1AP_SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge ;
|
||||
F1AP_GNBDUConfigurationUpdateAcknowledge_t *ack = &succOut->value.choice.GNBDUConfigurationUpdateAcknowledge;
|
||||
|
||||
/* Mandatory */
|
||||
/* Transaction Id */
|
||||
asn1cSequenceAdd(ack->protocolIEs.list, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID;
|
||||
ie1->value.choice.TransactionID = GNBDUConfigurationUpdateAcknowledge->transaction_id;
|
||||
|
||||
/* Todo add optional fields */
|
||||
/* encode */
|
||||
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 gNB-DU CONFIGURATION UPDATE\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_DUMPMSG(F1AP, LOG_DUMP_CHAR, buffer, len, "F1AP gNB-DU CONFIGURATION UPDATE : ");
|
||||
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -62,10 +62,10 @@ int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *
|
||||
int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id,
|
||||
F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure);
|
||||
f1ap_gnb_du_configuration_update_failure_t *GNBDUConfigurationUpdateFailure);
|
||||
|
||||
int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id,
|
||||
F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge);
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t *GNBDUConfigurationUpdateAcknowledge);
|
||||
|
||||
/*
|
||||
* gNB-CU Configuration Update
|
||||
|
||||
@@ -179,6 +179,9 @@ void *F1AP_CU_task(void *arg) {
|
||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
|
||||
CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(assoc_id,&F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(received_msg));
|
||||
break;
|
||||
case F1AP_DL_RRC_MESSAGE: // from rrc
|
||||
CU_send_DL_RRC_MESSAGE_TRANSFER(assoc_id,
|
||||
&F1AP_DL_RRC_MESSAGE(received_msg));
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
|
||||
#include "rrc_extern.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill)
|
||||
{
|
||||
@@ -163,7 +161,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
for (int i=0; i<1; i++) {
|
||||
asn1cSequenceAdd(ie7->value.choice.Candidate_SpCell_List.list,F1AP_Candidate_SpCell_ItemIEs_t, candidate_spCell_item_ies);
|
||||
candidate_spCell_item_ies->id = F1AP_ProtocolIE_ID_id_Candidate_SpCell_Item; // 91
|
||||
candidate_spCell_item_ies->criticality = F1AP_Criticality_reject;
|
||||
candidate_spCell_item_ies->criticality = F1AP_Criticality_ignore;
|
||||
candidate_spCell_item_ies->value.present = F1AP_Candidate_SpCell_ItemIEs__value_PR_Candidate_SpCell_Item;
|
||||
/* 7.1 Candidate_SpCell_Item */
|
||||
F1AP_Candidate_SpCell_Item_t *candidate_spCell_item=
|
||||
@@ -253,7 +251,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
for (int i=0; i<f1ap_ue_context_setup_req->srbs_to_be_setup_length; i++) {
|
||||
asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetup_List.list, F1AP_SRBs_ToBeSetup_ItemIEs_t, srbs_toBeSetup_item_ies);
|
||||
srbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73
|
||||
srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore;
|
||||
srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject;
|
||||
srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item;
|
||||
/* 11.1 SRBs_ToBeSetup_Item */
|
||||
F1AP_SRBs_ToBeSetup_Item_t *srbs_toBeSetup_item=&srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item;
|
||||
@@ -503,19 +501,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
|
||||
/* 12.1.3 uLUPTNLInformation_ToBeSetup_List */
|
||||
for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) {
|
||||
/*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/
|
||||
/* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */
|
||||
transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } };
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst,
|
||||
f1ap_ue_context_setup_req->gNB_CU_ue_id,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||
0xFFFF, // We will set the right value from DU answer
|
||||
-1, // no qfi
|
||||
addr, // We will set the right value from DU answer
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
||||
cu_f1u_data_req,
|
||||
NULL);
|
||||
DevAssert(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid > 0);
|
||||
/* 12.3.1 ULTunnels_ToBeSetup_Item */
|
||||
asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list,
|
||||
F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
|
||||
@@ -590,7 +576,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
if(f1ap_ue_context_setup_req->rrc_container_length > 0) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie14);
|
||||
ie14->id = F1AP_ProtocolIE_ID_id_RRCContainer;
|
||||
ie14->criticality = F1AP_Criticality_reject;
|
||||
ie14->criticality = F1AP_Criticality_ignore;
|
||||
ie14->value.present = F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer;
|
||||
OCTET_STRING_fromBuf(&ie14->value.choice.RRCContainer, (const char *)f1ap_ue_context_setup_req->rrc_container,
|
||||
f1ap_ue_context_setup_req->rrc_container_length);
|
||||
@@ -688,11 +674,6 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_
|
||||
F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
|
||||
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
|
||||
OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
|
||||
GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst,
|
||||
f1ap_ue_context_setup_resp->gNB_DU_ue_id,
|
||||
(ebi_t)drbs_setup_item_p->dRBID,
|
||||
drb_p->up_dl_tnl[0].tl_address,
|
||||
drb_p->up_dl_tnl[0].teid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1569,9 +1550,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
|
||||
&drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item;
|
||||
/* dRBID */
|
||||
drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id;
|
||||
newGtpuDeleteOneTunnel(getCxt(0)->gtpInst,
|
||||
f1ap_ue_context_modification_req->gNB_CU_ue_id,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1644,11 +1622,6 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t
|
||||
F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
|
||||
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
|
||||
OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
|
||||
GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst,
|
||||
f1ap_ue_context_modification_resp->gNB_CU_ue_id,
|
||||
(ebi_t)drbs_setupmod_item_p->dRBID,
|
||||
drb_p->up_dl_tnl[0].tl_address,
|
||||
drb_p->up_dl_tnl[0].teid);
|
||||
}
|
||||
}
|
||||
// SRBs_FailedToBeSetupMod_List
|
||||
|
||||
@@ -83,12 +83,145 @@ int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
/*
|
||||
F1 Setup
|
||||
*/
|
||||
static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_cell_info_t *c)
|
||||
{
|
||||
/* 4.1.1 served cell Information */
|
||||
F1AP_Served_Cell_Information_t scell_info = {0};
|
||||
addnRCGI(scell_info.nRCGI, c);
|
||||
|
||||
/* - nRPCI */
|
||||
scell_info.nRPCI = c->nr_pci; // int 0..1007
|
||||
|
||||
/* - fiveGS_TAC */
|
||||
if (c->tac != NULL) {
|
||||
uint32_t tac = htonl(*c->tac);
|
||||
asn1cCalloc(scell_info.fiveGS_TAC, netOrder);
|
||||
OCTET_STRING_fromBuf(netOrder, ((char *)&tac) + 1, 3);
|
||||
}
|
||||
|
||||
/* - Configured_EPS_TAC */
|
||||
if (0) {
|
||||
scell_info.configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t));
|
||||
OCTET_STRING_fromBuf(scell_info.configured_EPS_TAC, "2", 2);
|
||||
}
|
||||
|
||||
/* servedPLMN information */
|
||||
asn1cSequenceAdd(scell_info.servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item);
|
||||
MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity);
|
||||
|
||||
F1AP_NR_Mode_Info_t *nR_Mode_Info = &scell_info.nR_Mode_Info;
|
||||
F1AP_ProtocolExtensionContainer_10696P34_t *p = calloc(1, sizeof(*p));
|
||||
servedPLMN_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p;
|
||||
asn1cSequenceAdd(p->list, F1AP_ServedPLMNs_ItemExtIEs_t, served_plmns_itemExtIEs);
|
||||
served_plmns_itemExtIEs->criticality = F1AP_Criticality_ignore;
|
||||
served_plmns_itemExtIEs->id = F1AP_ProtocolIE_ID_id_TAISliceSupportList;
|
||||
served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList;
|
||||
F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList;
|
||||
|
||||
AssertFatal(c->num_ssi == 1, "can only encode one slice\n");
|
||||
for (int s = 0; s < c->num_ssi; s++) {
|
||||
asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, slice);
|
||||
INT8_TO_OCTET_STRING(c->sst, &slice->sNSSAI.sST);
|
||||
if (c->sd != 0xffffff) {
|
||||
asn1cCalloc(slice->sNSSAI.sD, tmp);
|
||||
INT24_TO_OCTET_STRING(c->sd, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (c->mode == F1AP_MODE_FDD) { // FDD
|
||||
const f1ap_fdd_info_t *fdd = &c->fdd;
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD;
|
||||
asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info);
|
||||
/* FDD.1.1 UL NRFreqInfo ARFCN */
|
||||
fDD_Info->uL_NRFreqInfo.nRARFCN = fdd->ul_freqinfo.arfcn; // Integer
|
||||
|
||||
/* FDD.1.2 F1AP_SUL_Information */
|
||||
|
||||
/* FDD.1.3 freqBandListNr */
|
||||
int ul_band = 1;
|
||||
for (int j = 0; j < ul_band; j++) {
|
||||
asn1cSequenceAdd(fDD_Info->uL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
/* FDD.1.3.1 freqBandIndicatorNr*/
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = fdd->ul_freqinfo.band;
|
||||
|
||||
/* FDD.1.3.2 supportedSULBandList*/
|
||||
}
|
||||
|
||||
/* FDD.2.1 DL NRFreqInfo ARFCN */
|
||||
fDD_Info->dL_NRFreqInfo.nRARFCN = fdd->dl_freqinfo.arfcn; // Integer
|
||||
|
||||
/* FDD.2.2 F1AP_SUL_Information */
|
||||
|
||||
/* FDD.2.3 freqBandListNr */
|
||||
int dl_bands = 1;
|
||||
for (int j = 0; j < dl_bands; j++) {
|
||||
asn1cSequenceAdd(fDD_Info->dL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
/* FDD.2.3.1 freqBandIndicatorNr*/
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = fdd->dl_freqinfo.band;
|
||||
|
||||
/* FDD.2.3.2 supportedSULBandList*/
|
||||
} // for FDD : DL freq_Bands
|
||||
|
||||
/* FDD.3 UL Transmission Bandwidth */
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRSCS = fdd->ul_tbw.scs;
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->ul_tbw.nrb);
|
||||
/* FDD.4 DL Transmission Bandwidth */
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRSCS = fdd->dl_tbw.scs;
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->dl_tbw.nrb);
|
||||
} else if (c->mode == F1AP_MODE_TDD) {
|
||||
const f1ap_tdd_info_t *tdd = &c->tdd;
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_tDD;
|
||||
asn1cCalloc(nR_Mode_Info->choice.tDD, tDD_Info);
|
||||
/* TDD.1.1 nRFreqInfo ARFCN */
|
||||
tDD_Info->nRFreqInfo.nRARFCN = tdd->freqinfo.arfcn;
|
||||
|
||||
/* TDD.1.2 F1AP_SUL_Information */
|
||||
|
||||
/* TDD.1.3 freqBandListNr */
|
||||
int bands = 1;
|
||||
for (int j = 0; j < bands; j++) {
|
||||
asn1cSequenceAdd(tDD_Info->nRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
/* TDD.1.3.1 freqBandIndicatorNr*/
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = tdd->freqinfo.band;
|
||||
/* TDD.1.3.2 supportedSULBandList*/
|
||||
}
|
||||
|
||||
/* TDD.2 transmission_Bandwidth */
|
||||
tDD_Info->transmission_Bandwidth.nRSCS = tdd->tbw.scs;
|
||||
tDD_Info->transmission_Bandwidth.nRNRB = to_NRNRB(tdd->tbw.nrb);
|
||||
} else {
|
||||
AssertFatal(false, "unknown mode %d\n", c->mode);
|
||||
}
|
||||
|
||||
/* - measurementTimingConfiguration */
|
||||
char *measurementTimingConfiguration = c->measurement_timing_information;
|
||||
OCTET_STRING_fromBuf(&scell_info.measurementTimingConfiguration,
|
||||
measurementTimingConfiguration,
|
||||
strlen(measurementTimingConfiguration));
|
||||
|
||||
return scell_info;
|
||||
}
|
||||
|
||||
|
||||
static F1AP_GNB_DU_System_Information_t *encode_system_info(const f1ap_gnb_du_system_info_t *sys_info)
|
||||
{
|
||||
if (sys_info == NULL)
|
||||
return NULL; /* optional: can be NULL */
|
||||
|
||||
F1AP_GNB_DU_System_Information_t *enc_sys_info = calloc(1, sizeof(*enc_sys_info));
|
||||
AssertFatal(enc_sys_info != NULL, "out of memory\n");
|
||||
|
||||
AssertFatal(sys_info->mib != NULL, "MIB must be present in DU sys info\n");
|
||||
OCTET_STRING_fromBuf(&enc_sys_info->mIB_message, (const char *)sys_info->mib, sys_info->mib_length);
|
||||
|
||||
AssertFatal(sys_info->sib1 != NULL, "SIB1 must be present in DU sys info\n");
|
||||
OCTET_STRING_fromBuf(&enc_sys_info->sIB1_message, (const char *)sys_info->sib1, sys_info->sib1_length);
|
||||
|
||||
return enc_sys_info;
|
||||
}
|
||||
|
||||
// SETUP REQUEST
|
||||
int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req)
|
||||
int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setup_req)
|
||||
{
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
uint8_t *buffer;
|
||||
@@ -139,151 +272,16 @@ int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req)
|
||||
for (int i=0; i<num_cells_available; i++) {
|
||||
/* mandatory */
|
||||
/* 4.1 served cells item */
|
||||
f1ap_served_cell_info_t *cell = &setup_req->cell[i].info;
|
||||
const f1ap_served_cell_info_t *cell = &setup_req->cell[i].info;
|
||||
const f1ap_gnb_du_system_info_t *sys_info = setup_req->cell[i].sys_info;
|
||||
asn1cSequenceAdd(ieCells->value.choice.GNB_DU_Served_Cells_List.list,
|
||||
F1AP_GNB_DU_Served_Cells_ItemIEs_t, duServedCell);
|
||||
duServedCell->id = F1AP_ProtocolIE_ID_id_GNB_DU_Served_Cells_Item;
|
||||
duServedCell->criticality = F1AP_Criticality_reject;
|
||||
duServedCell->value.present = F1AP_GNB_DU_Served_Cells_ItemIEs__value_PR_GNB_DU_Served_Cells_Item;
|
||||
F1AP_GNB_DU_Served_Cells_Item_t *gnb_du_served_cells_item=&duServedCell->value.choice.GNB_DU_Served_Cells_Item;
|
||||
/* 4.1.1 served cell Information */
|
||||
F1AP_Served_Cell_Information_t *served_cell_information= &gnb_du_served_cells_item->served_Cell_Information;
|
||||
addnRCGI(served_cell_information->nRCGI, cell);
|
||||
/* - nRPCI */
|
||||
served_cell_information->nRPCI = cell->nr_pci; // int 0..1007
|
||||
/* - fiveGS_TAC */
|
||||
if (cell->tac != NULL) {
|
||||
uint32_t tac=htonl(*cell->tac);
|
||||
asn1cCalloc(served_cell_information->fiveGS_TAC, netOrder);
|
||||
OCTET_STRING_fromBuf(netOrder, ((char *)&tac)+1, 3);
|
||||
}
|
||||
|
||||
/* - Configured_EPS_TAC */
|
||||
if(0) {
|
||||
served_cell_information->configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t));
|
||||
OCTET_STRING_fromBuf(served_cell_information->configured_EPS_TAC, "2", 2);
|
||||
}
|
||||
|
||||
/* servedPLMN information */
|
||||
asn1cSequenceAdd(served_cell_information->servedPLMNs.list, F1AP_ServedPLMNs_Item_t,servedPLMN_item);
|
||||
MCC_MNC_TO_PLMNID(cell->plmn.mcc, cell->plmn.mnc, cell->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity);
|
||||
// // /* - CHOICE NR-MODE-Info */
|
||||
F1AP_NR_Mode_Info_t *nR_Mode_Info= &served_cell_information->nR_Mode_Info;
|
||||
F1AP_ProtocolExtensionContainer_10696P34_t *p = calloc(1, sizeof(*p));
|
||||
servedPLMN_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *) p;
|
||||
asn1cSequenceAdd(p->list, F1AP_ServedPLMNs_ItemExtIEs_t , served_plmns_itemExtIEs);
|
||||
served_plmns_itemExtIEs->criticality = F1AP_Criticality_ignore;
|
||||
served_plmns_itemExtIEs->id = F1AP_ProtocolIE_ID_id_TAISliceSupportList;
|
||||
served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList;
|
||||
F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList;
|
||||
|
||||
/* get list of sst/sd from configuration file */
|
||||
paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC;
|
||||
paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0};
|
||||
char sstr[100];
|
||||
/* TODO: be sure that %d in the line below is at the right place */
|
||||
sprintf(sstr, "%s.[%d].%s.[0]", GNB_CONFIG_STRING_GNB_LIST, i, GNB_CONFIG_STRING_PLMN_LIST);
|
||||
config_getlist(config_get_if(), &SNSSAIParamList, SNSSAIParams, sizeofArray(SNSSAIParams), sstr);
|
||||
AssertFatal(SNSSAIParamList.numelt > 0, "no slice configuration found (snssaiList in the configuration file)\n");
|
||||
AssertFatal(SNSSAIParamList.numelt <= 1024, "maximum size for slice support list is 1024, see F1AP 38.473 9.3.1.37\n");
|
||||
for (int s = 0; s < SNSSAIParamList.numelt; s++) {
|
||||
uint32_t sst;
|
||||
uint32_t sd;
|
||||
bool has_sd;
|
||||
sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr;
|
||||
has_sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr != 0xffffff;
|
||||
asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, slice);
|
||||
INT8_TO_OCTET_STRING(sst, &slice->sNSSAI.sST);
|
||||
if (has_sd) {
|
||||
sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr;
|
||||
asn1cCalloc(slice->sNSSAI.sD, tmp);
|
||||
INT24_TO_OCTET_STRING(sd, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (setup_req->cell[i].info.mode == F1AP_MODE_FDD) { // FDD
|
||||
const f1ap_fdd_info_t *fdd = &setup_req->cell[i].info.fdd;
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD;
|
||||
asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info);
|
||||
/* FDD.1 UL NRFreqInfo */
|
||||
/* FDD.1.1 UL NRFreqInfo ARFCN */
|
||||
fDD_Info->uL_NRFreqInfo.nRARFCN = fdd->ul_freqinfo.arfcn; // Integer
|
||||
|
||||
/* FDD.1.2 F1AP_SUL_Information */
|
||||
|
||||
/* FDD.1.3 freqBandListNr */
|
||||
int fdd_ul_num_available_freq_Bands = 1;
|
||||
for (int fdd_ul_j=0; fdd_ul_j<fdd_ul_num_available_freq_Bands; fdd_ul_j++) {
|
||||
asn1cSequenceAdd(fDD_Info->uL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
/* FDD.1.3.1 freqBandIndicatorNr*/
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = fdd->ul_freqinfo.band;
|
||||
|
||||
/* FDD.1.3.2 supportedSULBandList*/
|
||||
} // for FDD : UL freq_Bands
|
||||
|
||||
/* FDD.2 DL NRFreqInfo */
|
||||
/* FDD.2.1 DL NRFreqInfo ARFCN */
|
||||
fDD_Info->dL_NRFreqInfo.nRARFCN = fdd->dl_freqinfo.arfcn; // Integer
|
||||
|
||||
/* FDD.2.2 F1AP_SUL_Information */
|
||||
|
||||
/* FDD.2.3 freqBandListNr */
|
||||
int fdd_dl_num_available_freq_Bands = 1;
|
||||
for (int fdd_dl_j=0; fdd_dl_j<fdd_dl_num_available_freq_Bands; fdd_dl_j++) {
|
||||
asn1cSequenceAdd(fDD_Info->dL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
/* FDD.2.3.1 freqBandIndicatorNr*/
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = fdd->dl_freqinfo.band;
|
||||
|
||||
/* FDD.2.3.2 supportedSULBandList*/
|
||||
} // for FDD : DL freq_Bands
|
||||
|
||||
/* FDD.3 UL Transmission Bandwidth */
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRSCS = fdd->ul_tbw.scs;
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->ul_tbw.nrb);
|
||||
/* FDD.4 DL Transmission Bandwidth */
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRSCS = fdd->dl_tbw.scs;
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->dl_tbw.nrb);
|
||||
} else if (setup_req->cell[i].info.mode == F1AP_MODE_TDD) { // TDD
|
||||
const f1ap_tdd_info_t *tdd = &setup_req->cell[i].info.tdd;
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_tDD;
|
||||
asn1cCalloc(nR_Mode_Info->choice.tDD, tDD_Info);
|
||||
/* TDD.1 nRFreqInfo */
|
||||
/* TDD.1.1 nRFreqInfo ARFCN */
|
||||
tDD_Info->nRFreqInfo.nRARFCN = tdd->freqinfo.arfcn; // Integer
|
||||
|
||||
/* TDD.1.2 F1AP_SUL_Information */
|
||||
|
||||
/* TDD.1.3 freqBandListNr */
|
||||
int tdd_num_available_freq_Bands = 1;
|
||||
for (int j=0; j<tdd_num_available_freq_Bands; j++) {
|
||||
asn1cSequenceAdd(tDD_Info->nRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
/* TDD.1.3.1 freqBandIndicatorNr*/
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = tdd->freqinfo.band;
|
||||
/* TDD.1.3.2 supportedSULBandList*/
|
||||
} // for TDD : freq_Bands
|
||||
|
||||
/* TDD.2 transmission_Bandwidth */
|
||||
tDD_Info->transmission_Bandwidth.nRSCS = tdd->tbw.scs;
|
||||
tDD_Info->transmission_Bandwidth.nRNRB = to_NRNRB(tdd->tbw.nrb);
|
||||
} else {
|
||||
AssertFatal(false, "unknown mode %d\n", setup_req->cell[i].info.mode);
|
||||
}
|
||||
|
||||
/* - measurementTimingConfiguration */
|
||||
char *measurementTimingConfiguration = cell->measurement_timing_information; // sept. 2018
|
||||
OCTET_STRING_fromBuf(&served_cell_information->measurementTimingConfiguration,
|
||||
measurementTimingConfiguration,
|
||||
strlen(measurementTimingConfiguration));
|
||||
|
||||
/* 4.1.2 gNB-DU System Information */
|
||||
if (setup_req->cell[i].sys_info != NULL) {
|
||||
asn1cCalloc(gnb_du_served_cells_item->gNB_DU_System_Information, gNB_DU_System_Information);
|
||||
const f1ap_gnb_du_system_info_t *sys_info = setup_req->cell[i].sys_info;
|
||||
AssertFatal(sys_info->mib != NULL, "MIB must be present in DU sys info\n");
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message, (const char *)sys_info->mib, sys_info->mib_length);
|
||||
AssertFatal(sys_info->sib1 != NULL, "SIB1 must be present in DU sys info\n");
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message, (const char *)sys_info->sib1, sys_info->sib1_length);
|
||||
}
|
||||
F1AP_GNB_DU_Served_Cells_Item_t *scell_item = &duServedCell->value.choice.GNB_DU_Served_Cells_Item;
|
||||
scell_item->served_Cell_Information = encode_served_cell_info(cell);
|
||||
scell_item->gNB_DU_System_Information = encode_system_info(sys_info);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
@@ -534,7 +532,7 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3
|
||||
gNB-DU Configuration Update
|
||||
*/
|
||||
|
||||
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_setup_req_t *f1ap_setup_req)
|
||||
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_t *upd)
|
||||
{
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
uint8_t *buffer=NULL;
|
||||
@@ -546,227 +544,91 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_setup_req_t
|
||||
initMsg->procedureCode = F1AP_ProcedureCode_id_gNBDUConfigurationUpdate;
|
||||
initMsg->criticality = F1AP_Criticality_reject;
|
||||
initMsg->value.present = F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate;
|
||||
F1AP_GNBDUConfigurationUpdate_t *out = &pdu.choice.initiatingMessage->value.choice.GNBDUConfigurationUpdate;
|
||||
F1AP_GNBDUConfigurationUpdate_t *out = &initMsg->value.choice.GNBDUConfigurationUpdate;
|
||||
|
||||
/* mandatory */
|
||||
/* c1. Transaction ID (integer value) */
|
||||
asn1cSequenceAdd(out, F1AP_GNBDUConfigurationUpdateIEs_t, ie1);
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_TransactionID;
|
||||
ie1->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0);
|
||||
ie1->value.choice.TransactionID = upd->transaction_id;
|
||||
|
||||
/* mandatory */
|
||||
/* c2. Served_Cells_To_Add */
|
||||
asn1cSequenceAdd(out, F1AP_GNBDUConfigurationUpdateIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Add_List;
|
||||
if (upd->num_cells_to_add > 0) {
|
||||
AssertFatal(false, "code for adding cells not tested\n");
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Add_List;
|
||||
|
||||
for (int j=0; j<1; j++) {
|
||||
//
|
||||
asn1cSequenceAdd(ie2->value.choice.Served_Cells_To_Add_List.list, F1AP_Served_Cells_To_Add_ItemIEs_t, served_cells_to_add_item_ies);
|
||||
served_cells_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_Item;
|
||||
served_cells_to_add_item_ies->criticality = F1AP_Criticality_reject;
|
||||
served_cells_to_add_item_ies->value.present = F1AP_Served_Cells_To_Add_ItemIEs__value_PR_Served_Cells_To_Add_Item;
|
||||
F1AP_Served_Cells_To_Add_Item_t *served_cells_to_add_item= &served_cells_to_add_item_ies->value.choice.Served_Cells_To_Add_Item;
|
||||
F1AP_Served_Cell_Information_t *served_cell_information=&served_cells_to_add_item->served_Cell_Information;
|
||||
/* - nRCGI */
|
||||
addnRCGI(served_cell_information->nRCGI, &f1ap_setup_req->cell[j].info);
|
||||
/* - nRPCI */
|
||||
/* 2.1.1 serverd cell Information */
|
||||
f1ap_served_cell_info_t *cell = &f1ap_setup_req->cell[j].info;
|
||||
served_cell_information->nRPCI = cell->nr_pci; // int 0..1007
|
||||
/* - fiveGS_TAC */
|
||||
if (cell->tac != NULL) {
|
||||
uint32_t tac = htonl(*cell->tac);
|
||||
served_cell_information->fiveGS_TAC = calloc(1, sizeof(*served_cell_information->fiveGS_TAC));
|
||||
OCTET_STRING_fromBuf(served_cell_information->fiveGS_TAC, ((char *)&tac)+1, 3);
|
||||
for (int j=0; j < upd->num_cells_to_add; j++) {
|
||||
const f1ap_served_cell_info_t *cell = &upd->cell_to_add[j].info;
|
||||
const f1ap_gnb_du_system_info_t *sys_info = upd->cell_to_add[j].sys_info;
|
||||
asn1cSequenceAdd(ie2->value.choice.Served_Cells_To_Add_List.list, F1AP_Served_Cells_To_Add_ItemIEs_t, served_cells_to_add_item_ies);
|
||||
served_cells_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_Item;
|
||||
served_cells_to_add_item_ies->criticality = F1AP_Criticality_reject;
|
||||
served_cells_to_add_item_ies->value.present = F1AP_Served_Cells_To_Add_ItemIEs__value_PR_Served_Cells_To_Add_Item;
|
||||
F1AP_Served_Cells_To_Add_Item_t *served_cells_to_add_item= &served_cells_to_add_item_ies->value.choice.Served_Cells_To_Add_Item;
|
||||
served_cells_to_add_item->served_Cell_Information = encode_served_cell_info(cell);
|
||||
served_cells_to_add_item->gNB_DU_System_Information = encode_system_info(sys_info);
|
||||
}
|
||||
|
||||
/* - Configured_EPS_TAC */
|
||||
if(1) {
|
||||
served_cell_information->configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t));
|
||||
OCTET_STRING_fromBuf(served_cell_information->configured_EPS_TAC,"2", 2);
|
||||
}
|
||||
|
||||
asn1cSequenceAdd(served_cell_information->servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item);
|
||||
MCC_MNC_TO_PLMNID(cell->plmn.mcc, cell->plmn.mnc, cell->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity);
|
||||
// // /* - CHOICE NR-MODE-Info */
|
||||
F1AP_NR_Mode_Info_t *nR_Mode_Info=&served_cell_information->nR_Mode_Info;
|
||||
LOG_E(F1AP,"Here hardcoded values instead of values from configuration file\n");
|
||||
|
||||
if (cell->mode == F1AP_MODE_FDD) {
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD;
|
||||
/* > FDD >> FDD Info */
|
||||
asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info);
|
||||
/* >>> UL NRFreqInfo */
|
||||
fDD_Info->uL_NRFreqInfo.nRARFCN = 999L;
|
||||
asn1cSequenceAdd(fDD_Info->uL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, ul_freqBandNrItem);
|
||||
ul_freqBandNrItem->freqBandIndicatorNr = 888L;
|
||||
asn1cSequenceAdd(ul_freqBandNrItem->supportedSULBandList.list, F1AP_SupportedSULFreqBandItem_t, ul_supportedSULFreqBandItem);
|
||||
ul_supportedSULFreqBandItem->freqBandIndicatorNr = 777L;
|
||||
/* >>> DL NRFreqInfo */
|
||||
fDD_Info->dL_NRFreqInfo.nRARFCN = 666L;
|
||||
asn1cSequenceAdd(fDD_Info->dL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, dl_freqBandNrItem);
|
||||
dl_freqBandNrItem->freqBandIndicatorNr = 555L;
|
||||
asn1cSequenceAdd(dl_freqBandNrItem->supportedSULBandList.list, F1AP_SupportedSULFreqBandItem_t, dl_supportedSULFreqBandItem);
|
||||
dl_supportedSULFreqBandItem->freqBandIndicatorNr = 444L;
|
||||
/* >>> UL Transmission Bandwidth */
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15;
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11;
|
||||
/* >>> DL Transmission Bandwidth */
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15;
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11;
|
||||
} else if (cell->mode == F1AP_MODE_TDD) { // TDD
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_tDD;
|
||||
/* > TDD >> TDD Info */
|
||||
asn1cCalloc(nR_Mode_Info->choice.tDD, tDD_Info);
|
||||
/* >>> ARFCN */
|
||||
tDD_Info->nRFreqInfo.nRARFCN = 999L; // Integer
|
||||
asn1cSequenceAdd(tDD_Info->nRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = 555L;
|
||||
asn1cSequenceAdd(nr_freqBandNrItem->supportedSULBandList.list, F1AP_SupportedSULFreqBandItem_t, nr_supportedSULFreqBandItem);
|
||||
nr_supportedSULFreqBandItem->freqBandIndicatorNr = 444L;
|
||||
tDD_Info->transmission_Bandwidth.nRSCS= F1AP_NRSCS_scs15;
|
||||
tDD_Info->transmission_Bandwidth.nRNRB= F1AP_NRNRB_nrb11;
|
||||
} else {
|
||||
AssertFatal(false, "illegal mode %d\n", cell->mode);
|
||||
}
|
||||
|
||||
/* - measurementTimingConfiguration */
|
||||
char *measurementTimingConfiguration = "0"; // sept. 2018
|
||||
OCTET_STRING_fromBuf(&served_cell_information->measurementTimingConfiguration,
|
||||
measurementTimingConfiguration,
|
||||
strlen(measurementTimingConfiguration));
|
||||
/* 2.1.2 gNB-DU System Information */
|
||||
asn1cCalloc(served_cells_to_add_item->gNB_DU_System_Information, gNB_DU_System_Information);
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message, // sept. 2018
|
||||
"1",
|
||||
sizeof("1"));
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message, // sept. 2018
|
||||
"1",
|
||||
sizeof("1"));
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* c3. Served_Cells_To_Modify */
|
||||
asn1cSequenceAdd(out, F1AP_GNBDUConfigurationUpdateIEs_t, ie3);
|
||||
ie3->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List;
|
||||
ie3->criticality = F1AP_Criticality_reject;
|
||||
ie3->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Modify_List;
|
||||
if (upd->num_cells_to_modify > 0) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie3);
|
||||
ie3->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List;
|
||||
ie3->criticality = F1AP_Criticality_reject;
|
||||
ie3->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Modify_List;
|
||||
for (int i = 0; i < upd->num_cells_to_modify; i++) {
|
||||
const f1ap_served_cell_info_t *cell = &upd->cell_to_modify[i].info;
|
||||
const f1ap_gnb_du_system_info_t *sys_info = upd->cell_to_modify[i].sys_info;
|
||||
asn1cSequenceAdd(ie3->value.choice.Served_Cells_To_Modify_List.list, F1AP_Served_Cells_To_Modify_ItemIEs_t, served_cells_to_modify_item_ies);
|
||||
served_cells_to_modify_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_Item;
|
||||
served_cells_to_modify_item_ies->criticality = F1AP_Criticality_reject;
|
||||
served_cells_to_modify_item_ies->value.present = F1AP_Served_Cells_To_Modify_ItemIEs__value_PR_Served_Cells_To_Modify_Item;
|
||||
F1AP_Served_Cells_To_Modify_Item_t *served_cells_to_modify_item=&served_cells_to_modify_item_ies->value.choice.Served_Cells_To_Modify_Item;
|
||||
|
||||
for (int i=0; i<1; i++) {
|
||||
//
|
||||
f1ap_served_cell_info_t *cell = &f1ap_setup_req->cell[i].info;
|
||||
asn1cSequenceAdd(ie3->value.choice.Served_Cells_To_Modify_List.list, F1AP_Served_Cells_To_Modify_ItemIEs_t, served_cells_to_modify_item_ies);
|
||||
served_cells_to_modify_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_Item;
|
||||
served_cells_to_modify_item_ies->criticality = F1AP_Criticality_reject;
|
||||
served_cells_to_modify_item_ies->value.present = F1AP_Served_Cells_To_Modify_ItemIEs__value_PR_Served_Cells_To_Modify_Item;
|
||||
F1AP_Served_Cells_To_Modify_Item_t *served_cells_to_modify_item=&served_cells_to_modify_item_ies->value.choice.Served_Cells_To_Modify_Item;
|
||||
/* 3.1 oldNRCGI */
|
||||
//addnRGCI(served_cells_to_modify_item->oldNRCGI, f1ap_setup_req->cell[i]);
|
||||
/* 3.2.1 serverd cell Information */
|
||||
F1AP_Served_Cell_Information_t *served_cell_information= &served_cells_to_modify_item->served_Cell_Information;
|
||||
/* - nRCGI */
|
||||
//addnRGCI(served_cell_information->nRCGI,f1ap_setup_req->cell[i]);
|
||||
/* - nRPCI */
|
||||
served_cell_information->nRPCI = cell->nr_pci; // int 0..1007
|
||||
/* - fiveGS_TAC */
|
||||
asn1cCalloc(served_cell_information->fiveGS_TAC, tac );
|
||||
OCTET_STRING_fromBuf(tac,
|
||||
(const char *) &cell->tac,
|
||||
3);
|
||||
F1AP_NRCGI_t *oldNRCGI = &served_cells_to_modify_item->oldNRCGI;
|
||||
const f1ap_plmn_t *old_plmn = &upd->cell_to_modify[i].old_plmn;
|
||||
MCC_MNC_TO_PLMNID(old_plmn->mcc, old_plmn->mnc, old_plmn->mnc_digit_length, &oldNRCGI->pLMN_Identity);
|
||||
NR_CELL_ID_TO_BIT_STRING(upd->cell_to_modify[i].old_nr_cellid, &oldNRCGI->nRCellIdentity);
|
||||
|
||||
/* - Configured_EPS_TAC */
|
||||
if(1) {
|
||||
asn1cCalloc(served_cell_information->configured_EPS_TAC, tmp2);
|
||||
OCTET_STRING_fromBuf(tmp2,
|
||||
"2",
|
||||
2);
|
||||
served_cells_to_modify_item->served_Cell_Information = encode_served_cell_info(cell);
|
||||
served_cells_to_modify_item->gNB_DU_System_Information = encode_system_info(sys_info);
|
||||
}
|
||||
|
||||
asn1cSequenceAdd(served_cell_information->servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item);
|
||||
MCC_MNC_TO_PLMNID(cell->plmn.mcc, cell->plmn.mnc, cell->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity);
|
||||
// // /* - CHOICE NR-MODE-Info */
|
||||
F1AP_NR_Mode_Info_t *nR_Mode_Info= &served_cell_information->nR_Mode_Info;
|
||||
|
||||
if (cell->mode == F1AP_MODE_FDD) {
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD;
|
||||
/* > FDD >> FDD Info */
|
||||
asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info);
|
||||
/* >>> UL NRFreqInfo */
|
||||
fDD_Info->uL_NRFreqInfo.nRARFCN = 999L;
|
||||
asn1cSequenceAdd(fDD_Info->uL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, ul_freqBandNrItem);
|
||||
ul_freqBandNrItem->freqBandIndicatorNr = 888L;
|
||||
asn1cSequenceAdd(ul_freqBandNrItem->supportedSULBandList.list, F1AP_SupportedSULFreqBandItem_t, ul_supportedSULFreqBandItem);
|
||||
ul_supportedSULFreqBandItem->freqBandIndicatorNr = 777L;
|
||||
/* >>> DL NRFreqInfo */
|
||||
fDD_Info->dL_NRFreqInfo.nRARFCN = 666L;
|
||||
asn1cSequenceAdd(dl_freqBandNrItem->supportedSULBandList.list, F1AP_FreqBandNrItem_t, dl_freqBandNrItem);
|
||||
dl_freqBandNrItem->freqBandIndicatorNr = 555L;
|
||||
F1AP_SupportedSULFreqBandItem_t dl_supportedSULFreqBandItem;
|
||||
memset((void *)&dl_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
|
||||
dl_supportedSULFreqBandItem.freqBandIndicatorNr = 444L;
|
||||
/* >>> UL Transmission Bandwidth */
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15;
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11;
|
||||
/* >>> DL Transmission Bandwidth */
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15;
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11;
|
||||
} else if (cell->mode == F1AP_MODE_TDD) { // TDD
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_tDD;
|
||||
/* > TDD >> TDD Info */
|
||||
asn1cCalloc(nR_Mode_Info->choice.tDD, tDD_Info);
|
||||
/* >>> ARFCN */
|
||||
tDD_Info->nRFreqInfo.nRARFCN = 999L; // Integer
|
||||
asn1cSequenceAdd(tDD_Info->nRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = 555L;
|
||||
asn1cSequenceAdd(nr_freqBandNrItem->supportedSULBandList.list, F1AP_SupportedSULFreqBandItem_t, nr_supportedSULFreqBandItem);
|
||||
nr_supportedSULFreqBandItem->freqBandIndicatorNr = 444L;
|
||||
tDD_Info->transmission_Bandwidth.nRSCS= F1AP_NRSCS_scs15;
|
||||
tDD_Info->transmission_Bandwidth.nRNRB= F1AP_NRNRB_nrb11;
|
||||
} else {
|
||||
AssertFatal(false, "unknown mode %d\n", cell->mode);
|
||||
}
|
||||
|
||||
/* - measurementTimingConfiguration */
|
||||
char *measurementTimingConfiguration = "0"; // sept. 2018
|
||||
OCTET_STRING_fromBuf(&served_cell_information->measurementTimingConfiguration,
|
||||
measurementTimingConfiguration,
|
||||
strlen(measurementTimingConfiguration));
|
||||
/* 3.2.2 gNB-DU System Information */
|
||||
asn1cCalloc( served_cells_to_modify_item->gNB_DU_System_Information, gNB_DU_System_Information);
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message, // sept. 2018
|
||||
"1",
|
||||
sizeof("1"));
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message, // sept. 2018
|
||||
"1",
|
||||
sizeof("1"));
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* c4. Served_Cells_To_Delete */
|
||||
asn1cSequenceAdd(out, F1AP_GNBDUConfigurationUpdateIEs_t, ie4);
|
||||
ie4->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List;
|
||||
ie4->criticality = F1AP_Criticality_reject;
|
||||
ie4->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Delete_List;
|
||||
|
||||
for (int i=0; i<1; i++) {
|
||||
//
|
||||
asn1cSequenceAdd(ie4->value.choice.Served_Cells_To_Delete_List.list, F1AP_Served_Cells_To_Delete_ItemIEs_t, served_cells_to_delete_item_ies);
|
||||
served_cells_to_delete_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_Item;
|
||||
served_cells_to_delete_item_ies->criticality = F1AP_Criticality_reject;
|
||||
served_cells_to_delete_item_ies->value.present = F1AP_Served_Cells_To_Delete_ItemIEs__value_PR_Served_Cells_To_Delete_Item;
|
||||
F1AP_Served_Cells_To_Delete_Item_t *served_cells_to_delete_item=&served_cells_to_delete_item_ies->value.choice.Served_Cells_To_Delete_Item;
|
||||
/* 3.1 oldNRCGI */
|
||||
addnRCGI(served_cells_to_delete_item->oldNRCGI, &f1ap_setup_req->cell[i].info);
|
||||
if (upd->num_cells_to_delete > 0) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie4);
|
||||
ie4->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List;
|
||||
ie4->criticality = F1AP_Criticality_reject;
|
||||
ie4->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Delete_List;
|
||||
AssertFatal(upd->num_cells_to_delete == 0, "code for deleting cells not tested\n");
|
||||
for (int i=0; i<upd->num_cells_to_delete; i++) {
|
||||
asn1cSequenceAdd(ie4->value.choice.Served_Cells_To_Delete_List.list, F1AP_Served_Cells_To_Delete_ItemIEs_t, served_cells_to_delete_item_ies);
|
||||
served_cells_to_delete_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_Item;
|
||||
served_cells_to_delete_item_ies->criticality = F1AP_Criticality_reject;
|
||||
served_cells_to_delete_item_ies->value.present = F1AP_Served_Cells_To_Delete_ItemIEs__value_PR_Served_Cells_To_Delete_Item;
|
||||
F1AP_Served_Cells_To_Delete_Item_t *served_cells_to_delete_item=&served_cells_to_delete_item_ies->value.choice.Served_Cells_To_Delete_Item;
|
||||
addnRCGI(served_cells_to_delete_item->oldNRCGI, &upd->cell_to_delete[i]);
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(upd->gNB_DU_ID == 0, "encoding of gNB-DU Id not handled yet\n");
|
||||
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 gNB-DU CONFIGURATION UPDATE\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3
|
||||
/*
|
||||
* F1 Setup
|
||||
*/
|
||||
int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req);
|
||||
int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setup_req);
|
||||
|
||||
int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
@@ -59,8 +59,7 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3
|
||||
/*
|
||||
* gNB-DU Configuration Update
|
||||
*/
|
||||
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id,
|
||||
f1ap_setup_req_t *f1ap_du_data);
|
||||
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_t *upd);
|
||||
|
||||
int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
|
||||
@@ -34,9 +34,10 @@
|
||||
#ifndef F1AP_DU_RRC_MESSAGE_TRANSFER_H_
|
||||
#define F1AP_DU_RRC_MESSAGE_TRANSFER_H_
|
||||
|
||||
#include "f1ap_common.h"
|
||||
#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
|
||||
|
||||
int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
struct F1AP_F1AP_PDU;
|
||||
int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, struct F1AP_F1AP_PDU *pdu);
|
||||
|
||||
int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_ul_rrc_message_t *msg);
|
||||
|
||||
|
||||
@@ -170,6 +170,10 @@ void *F1AP_DU_task(void *arg) {
|
||||
DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg));
|
||||
break;
|
||||
|
||||
case F1AP_GNB_DU_CONFIGURATION_UPDATE:
|
||||
DU_send_gNB_DU_CONFIGURATION_UPDATE(assoc_id, &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg));
|
||||
break;
|
||||
|
||||
case TERMINATE_MESSAGE:
|
||||
LOG_W(F1AP, " *** Exiting F1AP thread\n");
|
||||
itti_exit_task();
|
||||
|
||||
@@ -40,24 +40,6 @@
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
bool DURecvCb(protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
unsigned char *const sdu_buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id)
|
||||
{
|
||||
// The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue
|
||||
uint8_t *sdu = malloc16(sdu_buffer_sizeP);
|
||||
memcpy(sdu, sdu_buffer_pP, sdu_buffer_sizeP);
|
||||
du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu);
|
||||
return true;
|
||||
}
|
||||
|
||||
int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
F1AP_UEContextSetupRequest_t *container;
|
||||
@@ -305,6 +287,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set
|
||||
ie7->criticality = F1AP_Criticality_ignore;
|
||||
ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List;
|
||||
for (int i=0; i< resp->drbs_to_be_setup_length; i++) {
|
||||
f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i];
|
||||
//
|
||||
asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list,
|
||||
F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies);
|
||||
@@ -315,14 +298,17 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set
|
||||
/* ADD */
|
||||
F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item;
|
||||
/* dRBID */
|
||||
drbs_setup_item->dRBID = resp->drbs_to_be_setup[i].drb_id;
|
||||
drbs_setup_item->dRBID = drb->drb_id;
|
||||
|
||||
/* OPTIONAL */
|
||||
/* lCID */
|
||||
//drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t));
|
||||
//drbs_setup_item.lCID = 1L;
|
||||
|
||||
for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) {
|
||||
for (int j=0; j<drb->up_dl_tnl_length; j++) {
|
||||
const f1ap_up_tnl_t *tnl = &drb->up_dl_tnl[j];
|
||||
DevAssert(tnl->teid > 0);
|
||||
|
||||
/* ADD */
|
||||
asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list,
|
||||
F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item);
|
||||
@@ -330,12 +316,9 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set
|
||||
/* gTPTunnel */
|
||||
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel);
|
||||
/* transportLayerAddress */
|
||||
struct sockaddr_in addr= {0};
|
||||
inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr,
|
||||
&gTPTunnel->transportLayerAddress);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress);
|
||||
/* gTP_TEID */
|
||||
INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID);
|
||||
INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID);
|
||||
} // for j
|
||||
} // for i
|
||||
|
||||
@@ -1008,7 +991,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
|
||||
DevAssert(tbrel->id == F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item);
|
||||
DevAssert(tbrel->value.present == F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item);
|
||||
f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id = tbrel->value.choice.DRBs_ToBeReleased_Item.dRBID;
|
||||
newGtpuDeleteOneTunnel(0, f1ap_ue_context_modification_req->gNB_DU_ue_id, f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1166,20 +1148,8 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont
|
||||
drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id;
|
||||
|
||||
for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) {
|
||||
f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i];
|
||||
transport_layer_addr_t tl_addr = {0};
|
||||
memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address));
|
||||
tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8;
|
||||
drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst,
|
||||
resp->gNB_DU_ue_id,
|
||||
drb->drb_id,
|
||||
drb->drb_id,
|
||||
drb->up_ul_tnl[j].teid,
|
||||
-1, // no qfi
|
||||
tl_addr,
|
||||
drb->up_ul_tnl[0].port,
|
||||
DURecvCb,
|
||||
NULL);
|
||||
const f1ap_up_tnl_t *tnl = &resp->drbs_to_be_setup[i].up_dl_tnl[j];
|
||||
DevAssert(tnl->teid > 0);
|
||||
|
||||
/* ADD */
|
||||
asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list,
|
||||
@@ -1188,12 +1158,9 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont
|
||||
/* gTPTunnel */
|
||||
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel);
|
||||
/* transportLayerAddress */
|
||||
struct sockaddr_in addr= {0};
|
||||
inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr,
|
||||
&gTPTunnel->transportLayerAddress);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress);
|
||||
/* gTP_TEID */
|
||||
INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID);
|
||||
INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID);
|
||||
} // for j
|
||||
} // for i
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ static const f1ap_message_processing_t f1ap_messages_processing[][3] = {
|
||||
{0, 0, 0}, /* Reset */
|
||||
{CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE}, /* F1Setup */
|
||||
{0, 0, 0}, /* ErrorIndication */
|
||||
{0, 0, 0}, /* gNBDUConfigurationUpdate */
|
||||
{CU_handle_gNB_DU_CONFIGURATION_UPDATE, 0, 0}, /* gNBDUConfigurationUpdate */
|
||||
{DU_handle_gNB_CU_CONFIGURATION_UPDATE,
|
||||
CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE,
|
||||
CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE}, /* gNBCUConfigurationUpdate */
|
||||
|
||||
@@ -37,8 +37,8 @@ static pthread_mutex_t cu2du_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
void cu_init_f1_ue_data(void)
|
||||
{
|
||||
pthread_mutex_lock(&cu2du_mutex);
|
||||
DevAssert(cu2du_ue_mapping == NULL);
|
||||
cu2du_ue_mapping = hashtable_create(1319, NULL, free); // 1319 is prime, default hash func (unit), free()
|
||||
if (cu2du_ue_mapping == NULL) // hack: there is nothing to free this properly
|
||||
cu2du_ue_mapping = hashtable_create(1319, NULL, free); // 1319 is prime, default hash func (unit), free()
|
||||
DevAssert(cu2du_ue_mapping != NULL);
|
||||
pthread_mutex_unlock(&cu2du_mutex);
|
||||
}
|
||||
|
||||
@@ -1097,13 +1097,74 @@ static int read_du_cell_info(configmodule_interface_t *cfg,
|
||||
info->plmn.mnc_digit_length);
|
||||
info->nr_cellid = (uint64_t) * (GNBParamList.paramarray[0][GNB_NRCELLID_IDX].u64ptr);
|
||||
|
||||
LOG_W(GNB_APP, "no slices transported via F1 Setup Request!\n");
|
||||
info->num_ssi = 0;
|
||||
info->num_ssi = 1;
|
||||
paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC;
|
||||
checkedparam_t config_check_SNSSAIParams[] = SNSSAIPARAMS_CHECK;
|
||||
for (int J = 0; J < sizeof(SNSSAIParams) / sizeof(paramdef_t); ++J)
|
||||
SNSSAIParams[J].chkPptr = &(config_check_SNSSAIParams[J]);
|
||||
paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0};
|
||||
char snssaistr[MAX_OPTNAME_SIZE * 2 + 8];
|
||||
sprintf(snssaistr, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_PLMN_LIST, 0);
|
||||
config_getlist(config_get_if(), &SNSSAIParamList, SNSSAIParams, sizeof(SNSSAIParams) / sizeof(paramdef_t), snssaistr);
|
||||
AssertFatal(SNSSAIParamList.numelt == 1, "cannot handle no NSSAI or more than 1\n");
|
||||
info->sst = *SNSSAIParamList.paramarray[0][GNB_SLICE_SERVICE_TYPE_IDX].uptr;
|
||||
info->sd = *SNSSAIParamList.paramarray[0][GNB_SLICE_DIFFERENTIATOR_IDX].uptr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
|
||||
f1ap_tdd_info_t read_tdd_config(const NR_ServingCellConfigCommon_t *scc)
|
||||
{
|
||||
const NR_FrequencyInfoDL_t *dl = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||
f1ap_tdd_info_t tdd = {
|
||||
.freqinfo.arfcn = dl->absoluteFrequencyPointA,
|
||||
.freqinfo.band = *dl->frequencyBandList.list.array[0],
|
||||
.tbw.scs = dl->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
.tbw.nrb = dl->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
|
||||
};
|
||||
return tdd;
|
||||
}
|
||||
|
||||
static f1ap_fdd_info_t read_fdd_config(const NR_ServingCellConfigCommon_t *scc)
|
||||
{
|
||||
const NR_FrequencyInfoDL_t *dl = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||
const NR_FrequencyInfoUL_t *ul = scc->uplinkConfigCommon->frequencyInfoUL;
|
||||
f1ap_fdd_info_t fdd = {
|
||||
.dl_freqinfo.arfcn = dl->absoluteFrequencyPointA,
|
||||
.ul_freqinfo.arfcn = *ul->absoluteFrequencyPointA,
|
||||
.dl_tbw.scs = dl->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
.ul_tbw.scs = ul->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
.dl_tbw.nrb = dl->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
|
||||
.ul_tbw.nrb = ul->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
|
||||
.dl_freqinfo.band = *dl->frequencyBandList.list.array[0],
|
||||
.ul_freqinfo.band = *ul->frequencyBandList->list.array[0],
|
||||
};
|
||||
return fdd;
|
||||
}
|
||||
|
||||
f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1)
|
||||
{
|
||||
int buf_len = 3;
|
||||
f1ap_gnb_du_system_info_t *sys_info = calloc(1, sizeof(*sys_info));
|
||||
AssertFatal(sys_info != NULL, "out of memory\n");
|
||||
|
||||
sys_info->mib = calloc(buf_len, sizeof(*sys_info->mib));
|
||||
DevAssert(sys_info->mib != NULL);
|
||||
DevAssert(mib != NULL);
|
||||
sys_info->mib_length = encode_MIB_NR(mib, 0, sys_info->mib, buf_len);
|
||||
DevAssert(sys_info->mib_length == buf_len);
|
||||
|
||||
DevAssert(sib1 != NULL);
|
||||
NR_SIB1_t *bcch_SIB1 = sib1->message.choice.c1->choice.systemInformationBlockType1;
|
||||
sys_info->sib1 = calloc(NR_MAX_SIB_LENGTH / 8, sizeof(*sys_info->sib1));
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_SIB1, NULL, (void *)bcch_SIB1, sys_info->sib1, NR_MAX_SIB_LENGTH / 8);
|
||||
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
|
||||
sys_info->sib1_length = (enc_rval.encoded + 7) / 8;
|
||||
|
||||
return sys_info;
|
||||
}
|
||||
|
||||
f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
|
||||
const char *name,
|
||||
const f1ap_served_cell_info_t *info,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
@@ -1128,27 +1189,14 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
|
||||
req->cell[0].info.nr_cellid);
|
||||
|
||||
req->cell[0].info.nr_pci = *scc->physCellId;
|
||||
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||
if (scc->tdd_UL_DL_ConfigurationCommon) {
|
||||
LOG_I(GNB_APP, "ngran_DU: Configuring Cell %d for TDD\n", 0);
|
||||
req->cell[0].info.mode = F1AP_MODE_TDD;
|
||||
f1ap_tdd_info_t *tdd = &req->cell[0].info.tdd;
|
||||
tdd->freqinfo.arfcn = frequencyInfoDL->absoluteFrequencyPointA;
|
||||
tdd->tbw.scs = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
tdd->tbw.nrb = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
tdd->freqinfo.band = *frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
req->cell[0].info.tdd = read_tdd_config(scc);
|
||||
} else {
|
||||
LOG_I(GNB_APP, "ngran_DU: Configuring Cell %d for FDD\n", 0);
|
||||
req->cell[0].info.mode = F1AP_MODE_FDD;
|
||||
f1ap_fdd_info_t *fdd = &req->cell[0].info.fdd;
|
||||
fdd->dl_freqinfo.arfcn = frequencyInfoDL->absoluteFrequencyPointA;
|
||||
fdd->ul_freqinfo.arfcn = *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA;
|
||||
fdd->dl_tbw.scs = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
fdd->ul_tbw.scs = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
fdd->dl_tbw.nrb = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
fdd->ul_tbw.nrb = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
fdd->dl_freqinfo.band = *frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
fdd->ul_freqinfo.band = *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
|
||||
req->cell[0].info.fdd = read_fdd_config(scc);
|
||||
}
|
||||
|
||||
req->cell[0].info.measurement_timing_information = "0";
|
||||
@@ -1157,22 +1205,7 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
|
||||
// in NSA we don't transmit SIB1, so cannot fill DU system information
|
||||
// so cannot send MIB either
|
||||
|
||||
int buf_len = 3; // this is what we assume in monolithic
|
||||
req->cell[0].sys_info = calloc(1, sizeof(*req->cell[0].sys_info));
|
||||
AssertFatal(req->cell[0].sys_info != NULL, "out of memory\n");
|
||||
f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info;
|
||||
sys_info->mib = calloc(buf_len, sizeof(*sys_info->mib));
|
||||
DevAssert(sys_info->mib != NULL);
|
||||
DevAssert(mib != NULL);
|
||||
sys_info->mib_length = encode_MIB_NR(mib, 0, sys_info->mib, buf_len);
|
||||
DevAssert(sys_info->mib_length == buf_len);
|
||||
|
||||
DevAssert(sib1 != NULL);
|
||||
NR_SIB1_t *bcch_SIB1 = sib1->message.choice.c1->choice.systemInformationBlockType1;
|
||||
sys_info->sib1 = calloc(NR_MAX_SIB_LENGTH / 8, sizeof(*sys_info->sib1));
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_SIB1, NULL, (void *)bcch_SIB1, sys_info->sib1, NR_MAX_SIB_LENGTH / 8);
|
||||
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
|
||||
sys_info->sib1_length = (enc_rval.encoded + 7) / 8;
|
||||
req->cell[0].sys_info = get_sys_info(mib, sib1);
|
||||
}
|
||||
|
||||
int num = read_version(TO_STRING(NR_RRC_VERSION), &req->rrc_ver[0], &req->rrc_ver[1], &req->rrc_ver[2]);
|
||||
@@ -1569,7 +1602,6 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc)
|
||||
sprintf(aprefix,"%s.[%u].%s",GNB_CONFIG_STRING_GNB_LIST,i,GNB_CONFIG_STRING_SCTP_CONFIG);
|
||||
config_get(config_get_if(), SCTPParams, sizeofArray(SCTPParams), aprefix);
|
||||
LOG_I(GNB_APP,"F1AP: gNB_CU_id[%d] %d\n",k,rrc->node_id);
|
||||
rrc->node_name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr));
|
||||
LOG_I(GNB_APP,"F1AP: gNB_CU_name[%d] %s\n",k,rrc->node_name);
|
||||
rrc->eth_params_s.local_if_name = strdup(*(GNBParamList.paramarray[i][GNB_LOCAL_S_IF_NAME_IDX].strptr));
|
||||
rrc->eth_params_s.my_addr = strdup(*(GNBParamList.paramarray[i][GNB_LOCAL_S_ADDRESS_IDX].strptr));
|
||||
@@ -1583,6 +1615,7 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc)
|
||||
|
||||
|
||||
|
||||
rrc->node_name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr));
|
||||
rrc->nr_cellid = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr);
|
||||
|
||||
if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) {
|
||||
@@ -1644,6 +1677,17 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc)
|
||||
AssertFatal((nrrrc_config.mnc_digit_length[l] == 2) ||
|
||||
(nrrrc_config.mnc_digit_length[l] == 3),"BAD MNC DIGIT LENGTH %d",
|
||||
nrrrc_config.mnc_digit_length[l]);
|
||||
paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC;
|
||||
checkedparam_t config_check_SNSSAIParams[] = SNSSAIPARAMS_CHECK;
|
||||
for (int J = 0; J < sizeof(SNSSAIParams) / sizeof(paramdef_t); ++J)
|
||||
SNSSAIParams[J].chkPptr = &(config_check_SNSSAIParams[J]);
|
||||
paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0};
|
||||
char snssaistr[MAX_OPTNAME_SIZE * 2 + 8];
|
||||
sprintf(snssaistr, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_PLMN_LIST, l);
|
||||
config_getlist(config_get_if(), &SNSSAIParamList, SNSSAIParams, sizeof(SNSSAIParams) / sizeof(paramdef_t), snssaistr);
|
||||
AssertFatal(SNSSAIParamList.numelt == 1, "cannot handle no NSSAI or more than 1\n");
|
||||
nrrrc_config.sst = *SNSSAIParamList.paramarray[0][GNB_SLICE_SERVICE_TYPE_IDX].uptr;
|
||||
nrrrc_config.sd = *SNSSAIParamList.paramarray[0][GNB_SLICE_DIFFERENTIATOR_IDX].uptr;
|
||||
}
|
||||
nrrrc_config.enable_sdap = *GNBParamList.paramarray[i][GNB_ENABLE_SDAP_IDX].iptr;
|
||||
LOG_I(GNB_APP, "SDAP layer is %s\n", nrrrc_config.enable_sdap ? "enabled" : "disabled");
|
||||
|
||||
@@ -106,6 +106,12 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc);
|
||||
int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i);
|
||||
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i);
|
||||
void wait_f1_setup_response(void);
|
||||
f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
|
||||
const char *name,
|
||||
const f1ap_served_cell_info_t *info,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BCCH_BCH_Message_t *mib,
|
||||
const NR_BCCH_DL_SCH_Message_t *sib1);
|
||||
int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update);
|
||||
MessageDef *RCconfig_NR_CU_E1(const E1_t *entity);
|
||||
ngran_node_t get_node_type(void);
|
||||
|
||||
@@ -1683,7 +1683,8 @@ static void nr_generate_Msg4(module_id_t module_idP,
|
||||
|
||||
NR_UE_info_t *UE = find_nr_UE(&nr_mac->UE_info, ra->rnti);
|
||||
if (!UE) {
|
||||
LOG_E(NR_MAC, "want to generate Msg4, but rnti %04x not in the table\n", ra->rnti);
|
||||
LOG_E(NR_MAC, "want to generate Msg4, but rnti %04x not found. Abort RA\n", ra->rnti);
|
||||
nr_clear_ra_proc(0, 0, frameP, ra);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1936,7 +1937,7 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s
|
||||
LOG_A(NR_MAC, "(UE RNTI 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti);
|
||||
} else {
|
||||
LOG_I(NR_MAC, "%4d.%2d UE %04x: RA Procedure failed at Msg4!\n", frame, slot, ra->rnti);
|
||||
nr_mac_trigger_ul_failure(sched_ctrl, UE->current_DL_BWP.scs);
|
||||
nr_mac_trigger_ul_failure(UE->rnti);
|
||||
}
|
||||
|
||||
// Pause scheduling according to:
|
||||
|
||||
@@ -936,6 +936,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
NR_UEs_t *UE_info = &gNB_mac->UE_info;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
|
||||
const NR_BWP_t *initialDL = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
gNB_mac->mac_stats.total_prb_aggregate += NRRIV2BW(initialDL->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
UE_iterator(UE_info->list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP;
|
||||
@@ -1237,6 +1240,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS));
|
||||
UE->mac_stats.dl.total_rbs_retx += sched_pdsch->rbSize;
|
||||
gNB_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize;
|
||||
} else { /* initial transmission */
|
||||
LOG_D(NR_MAC, "Initial HARQ transmission in %d.%d\n", frame, slot);
|
||||
uint8_t *buf = (uint8_t *) harq->transportBlock;
|
||||
@@ -1353,6 +1357,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
UE->mac_stats.dl.num_mac_sdu += sdus;
|
||||
UE->mac_stats.dl.current_rbs = sched_pdsch->rbSize;
|
||||
UE->mac_stats.dl.total_sdu_bytes += dlsch_total_bytes;
|
||||
gNB_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize;
|
||||
|
||||
/* save retransmission information */
|
||||
harq->sched_pdsch = *sched_pdsch;
|
||||
|
||||
@@ -3064,15 +3064,22 @@ bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti)
|
||||
return sched_ctrl->release_timer == 0;
|
||||
}
|
||||
|
||||
void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing)
|
||||
void nr_mac_trigger_ul_failure(int rnti)
|
||||
{
|
||||
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti);
|
||||
if (UE == NULL) {
|
||||
LOG_E(NR_MAC, "could not find UE RNTI %04x\n", rnti);
|
||||
return;
|
||||
}
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
if (sched_ctrl->ul_failure) {
|
||||
/* already running */
|
||||
return;
|
||||
}
|
||||
sched_ctrl->ul_failure = true;
|
||||
// 30 seconds till triggering release request
|
||||
sched_ctrl->ul_failure_timer = 30000 << subcarrier_spacing;
|
||||
NR_SubcarrierSpacing_t subcarrier_spacing = UE->current_DL_BWP.scs;
|
||||
sched_ctrl->ul_failure_timer = 5000 << subcarrier_spacing;
|
||||
}
|
||||
|
||||
void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl)
|
||||
@@ -3097,7 +3104,7 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct
|
||||
.gNB_CU_ue_id = ue_data.secondary_ue,
|
||||
.gNB_DU_ue_id = rnti,
|
||||
.cause = F1AP_CAUSE_RADIO_NETWORK,
|
||||
.cause_value = F1AP_CauseRadioNetwork_rl_failure_others,
|
||||
.cause_value = F1AP_CauseRadioNetwork_rl_failure_rlc,
|
||||
};
|
||||
nrmac->mac_rrc.ue_context_release_request(&request);
|
||||
}
|
||||
|
||||
@@ -680,7 +680,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
"UE %04x: Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n",
|
||||
UE->rnti,
|
||||
UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt);
|
||||
nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
|
||||
nr_mac_trigger_ul_failure(UE->rnti);
|
||||
}
|
||||
}
|
||||
} else if(sduP) {
|
||||
|
||||
@@ -442,7 +442,7 @@ void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierS
|
||||
bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti);
|
||||
void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti);
|
||||
|
||||
void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing);
|
||||
void nr_mac_trigger_ul_failure(int rnti);
|
||||
void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
|
||||
@@ -23,8 +23,11 @@
|
||||
|
||||
#include "mac_proto.h"
|
||||
#include "openair2/F1AP/f1ap_ids.h"
|
||||
#include "openair2/F1AP/f1ap_common.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "F1AP_CauseRadioNetwork.h"
|
||||
#include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
#include "uper_decoder.h"
|
||||
#include "uper_encoder.h"
|
||||
@@ -34,6 +37,59 @@ const uint64_t qos_fiveqi[26] = {1, 2, 3, 4, 65, 66, 67, 71, 72, 73, 74, 76, 5,
|
||||
const uint64_t qos_priority[26] = {20, 40, 30, 50, 7, 20, 15, 56, 56, 56, 56, 56, 10,
|
||||
60, 70, 80, 90, 5, 55, 65, 68, 19, 22, 24, 21, 18};
|
||||
|
||||
static instance_t get_f1_gtp_instance(void)
|
||||
{
|
||||
const f1ap_cudu_inst_t *inst = getCxt(0);
|
||||
if (!inst)
|
||||
return -1; // means no F1
|
||||
return inst->gtpInst;
|
||||
}
|
||||
|
||||
static int drb_gtpu_create(instance_t instance,
|
||||
uint32_t ue_id,
|
||||
int incoming_id,
|
||||
int outgoing_id,
|
||||
int qfi,
|
||||
in_addr_t tlAddress, // only IPv4 now
|
||||
teid_t outgoing_teid,
|
||||
gtpCallback callBack,
|
||||
gtpCallbackSDAP callBackSDAP,
|
||||
gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp)
|
||||
{
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0};
|
||||
create_tunnel_req.incoming_rb_id[0] = incoming_id;
|
||||
create_tunnel_req.pdusession_id[0] = outgoing_id;
|
||||
memcpy(&create_tunnel_req.dst_addr[0].buffer, &tlAddress, sizeof(uint8_t) * 4);
|
||||
create_tunnel_req.dst_addr[0].length = 32;
|
||||
create_tunnel_req.outgoing_teid[0] = outgoing_teid;
|
||||
create_tunnel_req.outgoing_qfi[0] = qfi;
|
||||
create_tunnel_req.num_tunnels = 1;
|
||||
create_tunnel_req.ue_id = ue_id;
|
||||
|
||||
// we use gtpv1u_create_ngu_tunnel because it returns the interface
|
||||
// address and port of the interface; apart from that, we also might call
|
||||
// newGtpuCreateTunnel() directly
|
||||
return gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, callBack, callBackSDAP);
|
||||
}
|
||||
|
||||
bool DURecvCb(protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
unsigned char *const sdu_buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id)
|
||||
{
|
||||
// The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue
|
||||
uint8_t *sdu = malloc16(sdu_buffer_sizeP);
|
||||
memcpy(sdu, sdu_buffer_pP, sdu_buffer_sizeP);
|
||||
du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu);
|
||||
return true;
|
||||
}
|
||||
|
||||
static long get_lcid_from_drbid(int drb_id)
|
||||
{
|
||||
return drb_id + 3; /* LCID is DRB + 3 */
|
||||
@@ -88,6 +144,12 @@ void f1_setup_failure(const f1ap_setup_failure_t *failure)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *ack)
|
||||
{
|
||||
(void) ack;
|
||||
LOG_I(MAC, "received gNB-DU configuration update acknowledge\n");
|
||||
}
|
||||
|
||||
static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_setup_t *srb)
|
||||
{
|
||||
long priority = srb->srb_id; // high priority for SRB
|
||||
@@ -133,6 +195,7 @@ static int handle_ue_context_drbs_setup(int rnti,
|
||||
NR_CellGroupConfig_t *cellGroupConfig)
|
||||
{
|
||||
DevAssert(req_drbs != NULL && resp_drbs != NULL && cellGroupConfig != NULL);
|
||||
instance_t f1inst = get_f1_gtp_instance();
|
||||
|
||||
/* Note: the actual GTP tunnels are created in the F1AP breanch of
|
||||
* ue_context_*_response() */
|
||||
@@ -140,12 +203,32 @@ static int handle_ue_context_drbs_setup(int rnti,
|
||||
AssertFatal(*resp_drbs != NULL, "out of memory\n");
|
||||
for (int i = 0; i < drbs_len; i++) {
|
||||
const f1ap_drb_to_be_setup_t *drb = &req_drbs[i];
|
||||
f1ap_drb_to_be_setup_t *resp_drb = &(*resp_drbs)[i];
|
||||
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb);
|
||||
nr_rlc_add_drb(rnti, drb->drb_id, rlc_BearerConfig);
|
||||
|
||||
(*resp_drbs)[i] = *drb;
|
||||
*resp_drb = *drb;
|
||||
// just put same number of tunnels in DL as in UL
|
||||
(*resp_drbs)[i].up_dl_tnl_length = drb->up_ul_tnl_length;
|
||||
DevAssert(drb->up_ul_tnl_length == 1);
|
||||
resp_drb->up_dl_tnl_length = drb->up_ul_tnl_length;
|
||||
|
||||
if (f1inst >= 0) { // we actually use F1-U
|
||||
int qfi = -1; // don't put PDU session marker in GTP
|
||||
gtpv1u_gnb_create_tunnel_resp_t resp_f1 = {0};
|
||||
int ret = drb_gtpu_create(f1inst,
|
||||
rnti,
|
||||
drb->drb_id,
|
||||
drb->drb_id,
|
||||
qfi,
|
||||
drb->up_ul_tnl[0].tl_address,
|
||||
drb->up_ul_tnl[0].teid,
|
||||
DURecvCb,
|
||||
NULL,
|
||||
&resp_f1);
|
||||
AssertFatal(ret >= 0, "Unable to create GTP Tunnel for F1-U\n");
|
||||
memcpy(&resp_drb->up_dl_tnl[0].tl_address, &resp_f1.gnb_addr.buffer, 4);
|
||||
resp_drb->up_dl_tnl[0].teid = resp_f1.gnb_NGu_teid[0];
|
||||
}
|
||||
|
||||
int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
|
||||
DevAssert(ret == 0);
|
||||
@@ -159,6 +242,7 @@ static int handle_ue_context_drbs_release(int rnti,
|
||||
NR_CellGroupConfig_t *cellGroupConfig)
|
||||
{
|
||||
DevAssert(req_drbs != NULL && cellGroupConfig != NULL);
|
||||
instance_t f1inst = get_f1_gtp_instance();
|
||||
|
||||
cellGroupConfig->rlc_BearerToReleaseList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToReleaseList));
|
||||
AssertFatal(cellGroupConfig->rlc_BearerToReleaseList != NULL, "out of memory\n");
|
||||
@@ -178,6 +262,8 @@ static int handle_ue_context_drbs_release(int rnti,
|
||||
}
|
||||
if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) {
|
||||
nr_rlc_release_entity(rnti, lcid);
|
||||
if (f1inst >= 0)
|
||||
newGtpuDeleteOneTunnel(f1inst, rnti, drb->rb_id);
|
||||
asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1);
|
||||
long *plcid = malloc(sizeof(*plcid));
|
||||
AssertFatal(plcid != NULL, "out of memory\n");
|
||||
@@ -552,6 +638,10 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
instance_t f1inst = get_f1_gtp_instance();
|
||||
if (f1inst >= 0)
|
||||
newGtpuDeleteAllTunnels(f1inst, cmd->gNB_DU_ue_id);
|
||||
|
||||
if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) {
|
||||
/* The UE is already not connected anymore or we have nothing to forward*/
|
||||
nr_mac_release_ue(mac, cmd->gNB_DU_ue_id);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
void f1_setup_response(const f1ap_setup_resp_t *resp);
|
||||
void f1_setup_failure(const f1ap_setup_failure_t *failure);
|
||||
void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *ack);
|
||||
NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig);
|
||||
void ue_context_setup_request(const f1ap_ue_context_setup_t *req);
|
||||
void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "f1ap_messages_types.h"
|
||||
|
||||
typedef void (*f1_setup_request_func_t)(const f1ap_setup_req_t* req);
|
||||
typedef void (*gnb_du_configuration_update_t)(const f1ap_gnb_du_configuration_update_t *upd);
|
||||
|
||||
typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp);
|
||||
typedef void (*ue_context_modification_response_func_t)(const f1ap_ue_context_modif_req_t *req,
|
||||
|
||||
@@ -66,6 +66,51 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req)
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||
}
|
||||
|
||||
static void gnb_du_configuration_update_direct(const f1ap_gnb_du_configuration_update_t *upd)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE);
|
||||
msg->ittiMsgHeader.originInstance = -1; // means monolithic
|
||||
f1ap_gnb_du_configuration_update_t *f1ap_msg = &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg);
|
||||
DevAssert(upd->gNB_DU_ID == NULL);
|
||||
f1ap_msg->transaction_id = upd->transaction_id;
|
||||
DevAssert(upd->num_cells_to_add == 0);
|
||||
DevAssert(upd->num_cells_to_delete == 0);
|
||||
|
||||
f1ap_msg->num_cells_to_modify = upd->num_cells_to_modify;
|
||||
for (int n = 0; n < upd->num_cells_to_modify; ++n) {
|
||||
f1ap_msg->cell_to_modify[n].old_nr_cellid = upd->cell_to_modify[n].old_nr_cellid;
|
||||
f1ap_msg->cell_to_modify[n].info = upd->cell_to_modify[n].info; // copy most fields
|
||||
if (upd->cell_to_modify[n].info.tac) {
|
||||
f1ap_msg->cell_to_modify[n].info.tac = malloc(sizeof(*f1ap_msg->cell_to_modify[n].info.tac));
|
||||
AssertFatal(f1ap_msg->cell_to_modify[n].info.tac != NULL, "out of memory\n");
|
||||
*f1ap_msg->cell_to_modify[n].info.tac = *upd->cell_to_modify[n].info.tac;
|
||||
}
|
||||
if (upd->cell_to_modify[n].info.measurement_timing_information)
|
||||
f1ap_msg->cell_to_modify[n].info.measurement_timing_information = strdup(upd->cell_to_modify[n].info.measurement_timing_information);
|
||||
|
||||
if (upd->cell_to_modify[n].sys_info) {
|
||||
f1ap_gnb_du_system_info_t *orig_sys_info = upd->cell_to_modify[n].sys_info;
|
||||
f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info));
|
||||
AssertFatal(copy_sys_info != NULL, "out of memory\n");
|
||||
f1ap_msg->cell_to_modify[n].sys_info = copy_sys_info;
|
||||
|
||||
copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->mib != NULL, "out of memory\n");
|
||||
memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length);
|
||||
copy_sys_info->mib_length = orig_sys_info->mib_length;
|
||||
|
||||
if (orig_sys_info->sib1_length > 0) {
|
||||
copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->sib1 != NULL, "out of memory\n");
|
||||
memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length);
|
||||
copy_sys_info->sib1_length = orig_sys_info->sib1_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
|
||||
{
|
||||
DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
|
||||
@@ -227,6 +272,7 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const
|
||||
void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
||||
{
|
||||
mac_rrc->f1_setup_request = f1_setup_request_direct;
|
||||
mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_direct;
|
||||
mac_rrc->ue_context_setup_response = ue_context_setup_response_direct;
|
||||
mac_rrc->ue_context_modification_response = ue_context_modification_response_direct;
|
||||
mac_rrc->ue_context_modification_required = ue_context_modification_required_direct;
|
||||
|
||||
@@ -100,6 +100,39 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
|
||||
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void gnb_du_configuration_update_f1ap(const f1ap_gnb_du_configuration_update_t *upd)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE);
|
||||
f1ap_gnb_du_configuration_update_t *f1_upd = &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg);
|
||||
f1_upd->transaction_id = upd->transaction_id;
|
||||
AssertFatal(upd->num_cells_to_add == 0, "gNB-DU config update: cells to add not supported\n");
|
||||
f1_upd->num_cells_to_modify = upd->num_cells_to_modify;
|
||||
for (int n = 0; n < upd->num_cells_to_modify; ++n) {
|
||||
f1_upd->cell_to_modify[n].old_plmn = upd->cell_to_modify[n].old_plmn;
|
||||
f1_upd->cell_to_modify[n].old_nr_cellid = upd->cell_to_modify[n].old_nr_cellid;
|
||||
f1_upd->cell_to_modify[n].info = upd->cell_to_modify[n].info;
|
||||
if (upd->cell_to_modify[n].sys_info) {
|
||||
f1ap_gnb_du_system_info_t *orig_sys_info = upd->cell_to_modify[n].sys_info;
|
||||
f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info));
|
||||
f1_upd->cell_to_modify[n].sys_info = copy_sys_info;
|
||||
|
||||
copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->mib != NULL, "out of memory\n");
|
||||
memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length);
|
||||
copy_sys_info->mib_length = orig_sys_info->mib_length;
|
||||
|
||||
if (orig_sys_info->sib1_length > 0) {
|
||||
copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->sib1 != NULL, "out of memory\n");
|
||||
memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length);
|
||||
copy_sys_info->sib1_length = orig_sys_info->sib1_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
AssertFatal(upd->num_cells_to_delete == 0, "gNB-DU config update: cells to add not supported\n");
|
||||
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
|
||||
{
|
||||
DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
|
||||
@@ -239,6 +272,7 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1
|
||||
void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
||||
{
|
||||
mac_rrc->f1_setup_request = f1_setup_request_f1ap;
|
||||
mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_f1ap;
|
||||
mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap;
|
||||
mac_rrc->ue_context_modification_response = ue_context_modification_response_f1ap;
|
||||
mac_rrc->ue_context_modification_required = ue_context_modification_required_f1ap;
|
||||
|
||||
@@ -684,6 +684,7 @@ typedef struct NR_bler_options {
|
||||
|
||||
typedef struct nr_mac_rrc_ul_if_s {
|
||||
f1_setup_request_func_t f1_setup_request;
|
||||
gnb_du_configuration_update_t gnb_du_configuration_update;
|
||||
ue_context_setup_response_func_t ue_context_setup_response;
|
||||
ue_context_modification_response_func_t ue_context_modification_response;
|
||||
ue_context_modification_required_func_t ue_context_modification_required;
|
||||
@@ -743,6 +744,11 @@ typedef struct f1_config_t {
|
||||
uint32_t gnb_id; // associated gNB's ID, not used in DU itself
|
||||
} f1_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t total_prb_aggregate;
|
||||
uint64_t used_prb_aggregate;
|
||||
} mac_stats_t;
|
||||
|
||||
/*! \brief top level eNB MAC structure */
|
||||
typedef struct gNB_MAC_INST_s {
|
||||
/// Ethernet parameters for northbound midhaul interface
|
||||
@@ -862,6 +868,8 @@ typedef struct gNB_MAC_INST_s {
|
||||
|
||||
pthread_mutex_t sched_lock;
|
||||
|
||||
mac_stats_t mac_stats;
|
||||
|
||||
} gNB_MAC_INST;
|
||||
|
||||
#endif /*__LAYER2_NR_MAC_GNB_H__ */
|
||||
|
||||
@@ -569,6 +569,7 @@ rb_found:
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void nr_mac_trigger_ul_failure(int rnti);
|
||||
static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity)
|
||||
{
|
||||
nr_rlc_ue_t *ue = _ue;
|
||||
@@ -615,15 +616,7 @@ rb_found:
|
||||
if (!is_enb)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION);
|
||||
RLC_SDU_INDICATION(msg).rnti = ue->rnti;
|
||||
RLC_SDU_INDICATION(msg).is_successful = 0;
|
||||
RLC_SDU_INDICATION(msg).srb_id = rb_id;
|
||||
RLC_SDU_INDICATION(msg).message_id = -1;
|
||||
/* TODO: accept more than 1 instance? here we send to instance id 0 */
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, 0, msg);
|
||||
#endif
|
||||
nr_mac_trigger_ul_failure(ue->rnti);
|
||||
}
|
||||
|
||||
void nr_rlc_reestablish_entity(int rnti, int lc_id)
|
||||
|
||||
@@ -55,17 +55,7 @@ static bool resp_freelist_inited = false;
|
||||
|
||||
void init_sched_response(void)
|
||||
{
|
||||
/* init only once */
|
||||
if (pthread_mutex_lock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_lock failed\n");
|
||||
if (resp_freelist_inited) {
|
||||
if (pthread_mutex_unlock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_unlock failed\n");
|
||||
return;
|
||||
}
|
||||
resp_freelist_inited = true;
|
||||
if (pthread_mutex_unlock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_unlock failed\n");
|
||||
|
||||
int i;
|
||||
for (i = 0; i < N_RESP - 1; i++)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
typedef void (*f1_setup_response_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp);
|
||||
typedef void (*f1_setup_failure_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail);
|
||||
typedef void (*gnb_du_configuration_update_ack_func_t)(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_acknowledge_t *ack);
|
||||
|
||||
typedef void (*ue_context_setup_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req);
|
||||
typedef void (*ue_context_modification_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req);
|
||||
|
||||
@@ -36,6 +36,12 @@ static void f1_setup_failure_direct(sctp_assoc_t assoc_id, const f1ap_setup_fail
|
||||
f1_setup_failure(fail);
|
||||
}
|
||||
|
||||
static void gnb_du_configuration_update_ack_direct(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_acknowledge_t *ack)
|
||||
{
|
||||
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
|
||||
gnb_du_configuration_update_acknowledge(ack);
|
||||
}
|
||||
|
||||
static void ue_context_setup_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req)
|
||||
{
|
||||
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
|
||||
@@ -76,6 +82,7 @@ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
||||
{
|
||||
mac_rrc->f1_setup_response = f1_setup_response_direct;
|
||||
mac_rrc->f1_setup_failure = f1_setup_failure_direct;
|
||||
mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_direct;
|
||||
mac_rrc->ue_context_setup_request = ue_context_setup_request_direct;
|
||||
mac_rrc->ue_context_modification_request = ue_context_modification_request_direct;
|
||||
mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm_direct;
|
||||
|
||||
@@ -44,6 +44,15 @@ static void f1_setup_failure_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_failur
|
||||
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void gnb_du_configuration_update_ack_f1ap(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_acknowledge_t *ack)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE);
|
||||
msg->ittiMsgHeader.originInstance = assoc_id;
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t *f1ap_msg = &F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg);
|
||||
*f1ap_msg = *ack;
|
||||
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ);
|
||||
@@ -194,6 +203,7 @@ void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
||||
{
|
||||
mac_rrc->f1_setup_response = f1_setup_response_f1ap;
|
||||
mac_rrc->f1_setup_failure = f1_setup_failure_f1ap;
|
||||
mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_f1ap;
|
||||
mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap;
|
||||
mac_rrc->ue_context_modification_request = ue_context_modification_request_f1ap;
|
||||
mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm_f1ap;
|
||||
|
||||
@@ -829,6 +829,10 @@ void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsc
|
||||
void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
|
||||
|
||||
//TODO change to accomodate for SRS
|
||||
if (scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count > 0) {
|
||||
LOG_W(RRC, "%s(): already have pusch_TimeDomainAllocationList members, not adding more\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
const int k2 = min_fb_delay;
|
||||
|
||||
@@ -346,6 +346,7 @@ typedef struct {
|
||||
typedef struct nr_mac_rrc_dl_if_s {
|
||||
f1_setup_response_func_t f1_setup_response;
|
||||
f1_setup_failure_func_t f1_setup_failure;
|
||||
gnb_du_configuration_update_ack_func_t gnb_du_configuration_update_acknowledge;
|
||||
ue_context_setup_request_func_t ue_context_setup_request;
|
||||
ue_context_modification_request_func_t ue_context_modification_request;
|
||||
ue_context_modification_confirm_func_t ue_context_modification_confirm;
|
||||
|
||||
@@ -122,6 +122,20 @@ mui_t rrc_gNB_mui = 0;
|
||||
} \
|
||||
}
|
||||
|
||||
typedef struct deliver_ue_ctxt_release_data_t {
|
||||
gNB_RRC_INST *rrc;
|
||||
f1ap_ue_context_release_cmd_t *release_cmd;
|
||||
sctp_assoc_t assoc_id;
|
||||
} deliver_ue_ctxt_release_data_t;
|
||||
static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id)
|
||||
{
|
||||
DevAssert(deliver_pdu_data != NULL);
|
||||
deliver_ue_ctxt_release_data_t *data = deliver_pdu_data;
|
||||
data->release_cmd->rrc_container = (uint8_t*) buf;
|
||||
data->release_cmd->rrc_container_length = size;
|
||||
data->rrc->mac_rrc.ue_context_release_command(data->assoc_id, data->release_cmd);
|
||||
}
|
||||
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
|
||||
@@ -1834,7 +1848,18 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p)
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_CU_ue_id);
|
||||
if (!ue_context_p) {
|
||||
LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", req->gNB_CU_ue_id);
|
||||
LOG_W(RRC, "could not find UE context for CU UE ID %u: auto-generate release command\n", req->gNB_CU_ue_id);
|
||||
uint8_t buffer[RRC_BUF_SIZE] = {0};
|
||||
int size = do_NR_RRCRelease(buffer, RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(0));
|
||||
f1ap_ue_context_release_cmd_t ue_context_release_cmd = {
|
||||
.gNB_CU_ue_id = req->gNB_CU_ue_id,
|
||||
.gNB_DU_ue_id = req->gNB_DU_ue_id,
|
||||
.cause = F1AP_CAUSE_RADIO_NETWORK,
|
||||
.cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release
|
||||
.srb_id = DCCH,
|
||||
};
|
||||
deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd};
|
||||
nr_pdcp_data_req_srb(req->gNB_CU_ue_id, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2280,6 +2305,7 @@ void *rrc_gnb_task(void *args_p) {
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
LOG_W(NR_RRC, " *** Exiting NR_RRC thread\n");
|
||||
timer_remove(stats_timer_id);
|
||||
itti_exit_task();
|
||||
break;
|
||||
|
||||
@@ -2368,6 +2394,11 @@ void *rrc_gnb_task(void *args_p) {
|
||||
rrc_CU_process_f1_lost_connection(RC.nrrrc[0], &F1AP_LOST_CONNECTION(msg_p), msg_p->ittiMsgHeader.originInstance);
|
||||
break;
|
||||
|
||||
case F1AP_GNB_DU_CONFIGURATION_UPDATE:
|
||||
AssertFatal(!NODE_IS_DU(RC.nrrrc[instance]->node_type), "should not receive F1AP_SETUP_REQUEST in DU!\n");
|
||||
rrc_gNB_process_f1_du_configuration_update(&F1AP_GNB_DU_CONFIGURATION_UPDATE(msg_p), msg_p->ittiMsgHeader.originInstance);
|
||||
break;
|
||||
|
||||
/* Messages from X2AP */
|
||||
case X2AP_ENDC_SGNB_ADDITION_REQ:
|
||||
LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n");
|
||||
@@ -2534,20 +2565,6 @@ rrc_gNB_generate_UECapabilityEnquiry(
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue, DCCH, buffer, size);
|
||||
}
|
||||
|
||||
typedef struct deliver_ue_ctxt_release_data_t {
|
||||
gNB_RRC_INST *rrc;
|
||||
f1ap_ue_context_release_cmd_t *release_cmd;
|
||||
sctp_assoc_t assoc_id;
|
||||
} deliver_ue_ctxt_release_data_t;
|
||||
static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id)
|
||||
{
|
||||
DevAssert(deliver_pdu_data != NULL);
|
||||
deliver_ue_ctxt_release_data_t *data = deliver_pdu_data;
|
||||
data->release_cmd->rrc_container = (uint8_t*) buf;
|
||||
data->release_cmd->rrc_container_length = size;
|
||||
data->rrc->mac_rrc.ue_context_release_command(data->assoc_id, data->release_cmd);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* Generate the RRC Connection Release to UE.
|
||||
|
||||
@@ -48,6 +48,39 @@ static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell
|
||||
&& conf->mnc[0] == info->plmn.mnc;
|
||||
}
|
||||
|
||||
static bool extract_sys_info(const f1ap_gnb_du_system_info_t *sys_info, NR_BCCH_BCH_Message_t **mib, NR_SIB1_t **sib1)
|
||||
{
|
||||
DevAssert(sys_info != NULL);
|
||||
DevAssert(mib != NULL);
|
||||
DevAssert(sib1 != NULL);
|
||||
|
||||
asn_dec_rval_t dec_rval =
|
||||
uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)mib, sys_info->mib, sys_info->mib_length);
|
||||
if (dec_rval.code != RC_OK || (*mib)->message.present != NR_BCCH_BCH_MessageType_PR_mib
|
||||
|| (*mib)->message.choice.messageClassExtension == NULL) {
|
||||
LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU\n", dec_rval.consumed);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, *mib);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sys_info->sib1) {
|
||||
dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB1, (void **)sib1, sys_info->sib1, sys_info->sib1_length);
|
||||
if (dec_rval.code != RC_OK) {
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, *mib);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SIB1, *sib1);
|
||||
LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits), rejecting DU\n", dec_rval.consumed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_BCCH_BCH_Message, *mib);
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_SIB1, *sib1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
{
|
||||
AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n");
|
||||
@@ -110,35 +143,17 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
}
|
||||
}
|
||||
|
||||
// if there is no system info or no SIB1 and we run in SA mode, we cannot handle it
|
||||
const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info;
|
||||
NR_BCCH_BCH_Message_t *mib = NULL;
|
||||
NR_SIB1_t *sib1 = NULL;
|
||||
|
||||
if (sys_info != NULL && sys_info->mib != NULL && !(sys_info->sib1 == NULL && get_softmodem_params()->sa)) {
|
||||
asn_dec_rval_t dec_rval =
|
||||
uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&mib, sys_info->mib, sys_info->mib_length);
|
||||
if (dec_rval.code != RC_OK || mib->message.present != NR_BCCH_BCH_MessageType_PR_mib
|
||||
|| mib->message.choice.messageClassExtension == NULL) {
|
||||
LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU\n", dec_rval.consumed);
|
||||
if (!extract_sys_info(sys_info, &mib, &sib1)) {
|
||||
LOG_W(RRC, "rejecting DU ID %ld\n", req->gNB_DU_id);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, mib);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sys_info->sib1) {
|
||||
dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB1, (void **)&sib1, sys_info->sib1, sys_info->sib1_length);
|
||||
if (dec_rval.code != RC_OK) {
|
||||
LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU\n", dec_rval.consumed);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SIB1, sib1);
|
||||
return;
|
||||
}
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_SIB1, sib1);
|
||||
}
|
||||
}
|
||||
LOG_I(RRC, "Accepting DU %ld (%s), sending F1 Setup Response\n", req->gNB_DU_id, req->gNB_DU_name);
|
||||
LOG_I(RRC, "DU uses RRC version %u.%u.%u\n", req->rrc_ver[0], req->rrc_ver[1], req->rrc_ver[2]);
|
||||
@@ -154,12 +169,11 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
du->setup_req = calloc(1,sizeof(*du->setup_req));
|
||||
AssertFatal(du->setup_req != NULL, "out of memory\n");
|
||||
*du->setup_req = *req;
|
||||
if (mib != NULL && sib1 != NULL) {
|
||||
du->mib = mib->message.choice.mib;
|
||||
mib->message.choice.mib = NULL;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib);
|
||||
du->sib1 = sib1;
|
||||
}
|
||||
DevAssert(mib != NULL);
|
||||
du->mib = mib->message.choice.mib;
|
||||
mib->message.choice.mib = NULL;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib);
|
||||
du->sib1 = sib1;
|
||||
RB_INSERT(rrc_du_tree, &rrc->dus, du);
|
||||
rrc->num_dus++;
|
||||
|
||||
@@ -178,28 +192,6 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
if (rrc->node_name != NULL)
|
||||
resp.gNB_CU_name = strdup(rrc->node_name);
|
||||
rrc->mac_rrc.f1_setup_response(assoc_id, &resp);
|
||||
|
||||
/*
|
||||
MessageDef *msg_p2 = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE);
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).gNB_CU_name = rrc->node_name;
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mcc = rrc->configuration.mcc[0];
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc = rrc->configuration.mnc[0];
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0];
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nr_cellid = rrc->nr_cellid;
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nrpci = req->cell[0].info.nr_pci;
|
||||
int num_SI = 0;
|
||||
|
||||
if (rrc->carrier.SIB23) {
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container[2] = rrc->carrier.SIB23;
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container_length[2] = rrc->carrier.sizeof_SIB23;
|
||||
num_SI++;
|
||||
}
|
||||
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].num_SI = num_SI;
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).num_cells_to_activate = 1;
|
||||
// send
|
||||
itti_send_msg_to_task(TASK_CU_F1, 0, msg_p2);
|
||||
*/
|
||||
}
|
||||
|
||||
static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id)
|
||||
@@ -221,6 +213,103 @@ static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id)
|
||||
return count;
|
||||
}
|
||||
|
||||
static void update_cell_info(nr_rrc_du_container_t *du, const f1ap_served_cell_info_t *new_ci)
|
||||
{
|
||||
DevAssert(du != NULL);
|
||||
DevAssert(new_ci != NULL);
|
||||
|
||||
AssertFatal(du->setup_req->num_cells_available == 1, "expected 1 cell for DU, but has %d\n", du->setup_req->num_cells_available);
|
||||
f1ap_served_cell_info_t *ci = &du->setup_req->cell[0].info;
|
||||
|
||||
ci->nr_cellid = new_ci->nr_cellid;
|
||||
ci->nr_pci = new_ci->nr_pci;
|
||||
if (new_ci->tac != NULL)
|
||||
*ci->tac = *new_ci->tac;
|
||||
ci->num_ssi = new_ci->num_ssi;
|
||||
ci->sst = new_ci->sst;
|
||||
ci->sd = new_ci->sd;
|
||||
ci->mode = new_ci->mode;
|
||||
if (ci->mode == F1AP_MODE_TDD)
|
||||
ci->tdd = new_ci->tdd;
|
||||
else
|
||||
ci->fdd = new_ci->fdd;
|
||||
}
|
||||
|
||||
void rrc_gNB_process_f1_du_configuration_update(f1ap_gnb_du_configuration_update_t *conf_up, sctp_assoc_t assoc_id)
|
||||
{
|
||||
AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n");
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||
DevAssert(rrc);
|
||||
|
||||
// check:
|
||||
// - it is one cell
|
||||
// - PLMN and Cell ID matches
|
||||
// - no previous DU with the same ID
|
||||
// else reject
|
||||
|
||||
nr_rrc_du_container_t *du = get_du_by_assoc_id(rrc, assoc_id);
|
||||
AssertError(du != NULL, return, "no DU found for assoc_id %d\n", assoc_id);
|
||||
|
||||
const f1ap_served_cell_info_t *info = &du->setup_req->cell[0].info;
|
||||
if(conf_up->num_cells_to_add > 0){
|
||||
// Here we check if the number of cell limit is respectet, otherwise send failure
|
||||
LOG_W(RRC, "du_configuration_update->cells_to_add_list is not supported yet");
|
||||
}
|
||||
|
||||
if(conf_up->num_cells_to_modify > 0){
|
||||
// here the old nrcgi is used to find the cell information, if it exist then we modify consequently otherwise we fail
|
||||
AssertFatal(conf_up->num_cells_to_modify == 1, "cannot handle more than one cell!\n");
|
||||
|
||||
if (info->nr_cellid != conf_up->cell_to_modify[0].old_nr_cellid) {
|
||||
LOG_W(RRC, "no cell with ID %ld found, ignoring gNB-DU configuration update\n", conf_up->cell_to_modify[0].old_nr_cellid);
|
||||
return;
|
||||
}
|
||||
|
||||
// verify the new plmn of the cell
|
||||
if (!rrc_gNB_plmn_matches(rrc, &conf_up->cell_to_modify[0].info)) {
|
||||
LOG_W(RRC, "PLMN does not match, ignoring gNB-DU configuration update\n");
|
||||
return;
|
||||
}
|
||||
|
||||
update_cell_info(du, &conf_up->cell_to_modify[0].info);
|
||||
|
||||
const f1ap_gnb_du_system_info_t *sys_info = conf_up->cell_to_modify[0].sys_info;
|
||||
|
||||
if (sys_info != NULL && sys_info->mib != NULL && !(sys_info->sib1 == NULL && get_softmodem_params()->sa)) {
|
||||
// MIB is mandatory, so will be overwritten. SIB1 is optional, so will
|
||||
// only be overwritten if present in sys_info
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_MIB, du->mib);
|
||||
if (sys_info->sib1 != NULL) {
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SIB1, du->sib1);
|
||||
du->sib1 = NULL;
|
||||
}
|
||||
|
||||
NR_BCCH_BCH_Message_t *mib = NULL;
|
||||
|
||||
if (!extract_sys_info(sys_info, &mib, &du->sib1)) {
|
||||
LOG_W(RRC, "cannot update sys_info for DU %ld\n", du->setup_req->gNB_DU_id);
|
||||
} else {
|
||||
DevAssert(mib != NULL);
|
||||
du->mib = mib->message.choice.mib;
|
||||
mib->message.choice.mib = NULL;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib);
|
||||
LOG_I(RRC, "update system information of DU %ld\n", du->setup_req->gNB_DU_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(conf_up->num_cells_to_delete > 0){
|
||||
// delete the cell and send cell to desactive IE in the response.
|
||||
LOG_W(RRC, "du_configuration_update->cells_to_delete_list is not supported yet");
|
||||
}
|
||||
|
||||
|
||||
/* Send DU Configuration Acknowledgement */
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t ack = {.transaction_id = conf_up->transaction_id};
|
||||
|
||||
rrc->mac_rrc.gnb_du_configuration_update_acknowledge(assoc_id, &ack);
|
||||
}
|
||||
|
||||
void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id)
|
||||
{
|
||||
AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n");
|
||||
@@ -276,5 +365,18 @@ void dump_du_info(const gNB_RRC_INST *rrc, FILE *f)
|
||||
}
|
||||
const f1ap_served_cell_info_t *info = &sr->cell[0].info;
|
||||
fprintf(f, ": nrCellID %ld, PCI %d\n", info->nr_cellid, info->nr_pci);
|
||||
|
||||
if (info->mode == F1AP_MODE_TDD) {
|
||||
const f1ap_nr_frequency_info_t *fi = &info->tdd.freqinfo;
|
||||
const f1ap_transmission_bandwidth_t *tb = &info->tdd.tbw;
|
||||
fprintf(f, " TDD: band %d ARFCN %d SCS %d (kHz) PRB %d\n", fi->band, fi->arfcn, 15 * (1 << tb->scs), tb->nrb);
|
||||
} else {
|
||||
const f1ap_nr_frequency_info_t *dfi = &info->fdd.dl_freqinfo;
|
||||
const f1ap_transmission_bandwidth_t *dtb = &info->fdd.dl_tbw;
|
||||
fprintf(f, " FDD: DL band %d ARFCN %d SCS %d (kHz) PRB %d\n", dfi->band, dfi->arfcn, 15 * ( 1 << dtb->scs), dtb->nrb);
|
||||
const f1ap_nr_frequency_info_t *ufi = &info->fdd.ul_freqinfo;
|
||||
const f1ap_transmission_bandwidth_t *utb = &info->fdd.ul_tbw;
|
||||
fprintf(f, " UL band %d ARFCN %d SCS %d (kHz) PRB %d\n", ufi->band, ufi->arfcn, 15 * (1 << utb->scs), utb->nrb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,9 +31,11 @@ struct f1ap_setup_req_s;
|
||||
struct f1ap_lost_connection_t;
|
||||
struct gNB_RRC_INST_s;
|
||||
struct nr_rrc_du_container_t;
|
||||
struct f1ap_gnb_du_configuration_update_s;
|
||||
|
||||
void rrc_gNB_process_f1_setup_req(struct f1ap_setup_req_s *req, sctp_assoc_t assoc_id);
|
||||
void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, struct f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id);
|
||||
void rrc_gNB_process_f1_du_configuration_update(struct f1ap_gnb_du_configuration_update_s *conf_up, sctp_assoc_t assoc_id);
|
||||
|
||||
struct nr_rrc_du_container_t *get_du_for_ue(struct gNB_RRC_INST_s *rrc, uint32_t ue_id);
|
||||
struct nr_rrc_du_container_t *get_du_by_assoc_id(struct gNB_RRC_INST_s *rrc, sctp_assoc_t assoc_id);
|
||||
|
||||
@@ -670,6 +670,15 @@ static int startServer(openair0_device *device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rfsimulator_end(openair0_device *device);
|
||||
static void stopServer(openair0_device *device)
|
||||
{
|
||||
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
|
||||
DevAssert(t != NULL);
|
||||
rfsimulator_end(device);
|
||||
close(t->listen_sock);
|
||||
}
|
||||
|
||||
static int startClient(openair0_device *device) {
|
||||
rfsimulator_state_t *t = device->priv;
|
||||
t->role = SIMU_ROLE_CLIENT;
|
||||
@@ -1047,10 +1056,11 @@ static void rfsimulator_end(openair0_device *device) {
|
||||
rfsimulator_state_t* s = device->priv;
|
||||
for (int i = 0; i < MAX_FD_RFSIMU; i++) {
|
||||
buffer_t *b = &s->buf[i];
|
||||
if (b->conn_sock >= 0 )
|
||||
close(b->conn_sock);
|
||||
if (b->conn_sock >= 0 ) {
|
||||
removeCirBuf(s, b->conn_sock);
|
||||
}
|
||||
}
|
||||
close(s->epollfd);
|
||||
//close(s->epollfd); // don't close as we cannot restart with startServer()/startClient()
|
||||
}
|
||||
static int rfsimulator_stop(openair0_device *device) {
|
||||
return 0;
|
||||
@@ -1084,7 +1094,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
device->trx_start_func = rfsimulator->role == SIMU_ROLE_SERVER ? startServer : startClient;
|
||||
device->trx_get_stats_func = rfsimulator_get_stats;
|
||||
device->trx_reset_stats_func = rfsimulator_reset_stats;
|
||||
device->trx_end_func = rfsimulator_end;
|
||||
device->trx_end_func = rfsimulator->role == SIMU_ROLE_SERVER ? stopServer : rfsimulator_end;
|
||||
device->trx_stop_func = rfsimulator_stop;
|
||||
device->trx_set_freq_func = rfsimulator_set_freq;
|
||||
device->trx_set_gains_func = rfsimulator_set_gains;
|
||||
|
||||
Reference in New Issue
Block a user