Commit 607f192c authored by batuhan duyuler's avatar batuhan duyuler

Neigbourcell Configuration - Measurement Configuration for Inter gNB - N2 Handover

- NeighbourCell and Measurement Configurations are prepared.

NeighbourCell Configuration includes:
	- neighbour_gNB_ID (This is needed for AMF to identify gNB exists in it's context
	- neighbour_nr_cell_id (This is needed for target gNB)
	- neighbour_physical_cellId (This is needed for UE in the meas report)
	- neighbour_absoluteFrequencySSB (This is needed for UE in meas report)
	- neighbour_subcarrierSpacing (This is needed for UE in meas report)
	- neighbour_mnc (This is needed for AMF)
	- neighbour_mcc (This is needed for AMF)
	- neighbour_mnc_length (This is needed for AMF)
	- neighbour_tracking_area_code (This is needed for AMF)

NR Measurement Event Configuration Includes:
	- enableA2 & enableA3 (gNB activates the event reporting according to these vars)
	- thresholdA2 & A2_TTT (configurable reporting parameters)
	- thresholdA3 & A3_Hysteresis & A3_TTT (configurable reporting parameters)

- These parameters are read in the configuration parsing part and written under RRC structure
- Event Based Measurement Configuration is prepared according to enableA3 parameter.
- Measurement Configuration of UE is cloned under UE Context. When a measurement report comes,
looping through the UE's meas config and matching the measIDs. With this measID, report configs
extracted and processing in different ways.
parent c599e172
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; sd = 0x1; }) });
neighbour_cell_configuration = (
{
internal_neighbour_id = 0; #For MultiCell Purposes
neighbour_gNB_ID = 0xb00;
neighbour_nr_cellid = 1;
neighbour_physical_cellId = 0x001;
neighbour_absoluteFrequencySSB = 621600 ;
neighbour_subcarrierSpacing = 1; #30 KHz
neighbour_mcc = 999;
neighbour_mnc = 99;
neighbour_mnc_length = 2;
neighbour_tac = 1;
},
{ #For test : source gNB as neighbour gNB
internal_neighbour_id = 1;
neighbour_gNB_ID = 0xe00;
neighbour_nr_cellid = 12345678L;
neighbour_physical_cellId = 0;
neighbour_absoluteFrequencySSB = 621312 ;
neighbour_subcarrierSpacing = 1; #30 KHz
neighbour_mcc = 001;
neighbour_mnc = 01;
neighbour_mnc_length = 2;
neighbour_tac = 1;
},
);
nr_measurement_event_configuration = {
enableA2 = 1;
enableA3 = 1;
thresholdA2 = 60; # 5dB
A2_timeToTrigger = 1;
A3_offset = 10; # 5dB
A3_hysteresis = 0;
A3_timeToTrigger = 1; # ms40
};
nr_cellid = 12345678L;
////////// Physical parameters:
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 = 621312;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 620040;
#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 = 5;
nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 8;
nrofUplinkSlots = 1;
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 = "oaicore";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129";
GNB_INTERFACE_NAME_FOR_NGU = "oaicore";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 300;
pucch_TargetSNRx10 = 200;
ulsch_max_frame_inactivity = 0;
ul_max_mcs = 28;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 100;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0;
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
#sdr_addrs ="3231EEC";
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";
};
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
ngap_log_level ="info";
f1ap_log_level ="info";
};
...@@ -1607,8 +1607,46 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc) ...@@ -1607,8 +1607,46 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc)
char gnbpath[MAX_OPTNAME_SIZE + 8]; char gnbpath[MAX_OPTNAME_SIZE + 8];
sprintf(gnbpath,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k); sprintf(gnbpath,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k);
paramdef_t NeighbourCellParams[] = GNBNEIGHBOURCELLPARAMS_DESC;
paramlist_def_t NeighbourCellParamList = {GNB_CONFIG_STRING_NEIGHBOUR_CELL_LIST, NULL, 0};
config_getlist(config_get_if(), &NeighbourCellParamList, NeighbourCellParams, sizeofArray(NeighbourCellParams), gnbpath);
LOG_I(NR_MAC, "HO LOG: Neighbour Cell ELM NUM: %d\n", NeighbourCellParamList.numelt);
for (uint8_t l = 0; l < NeighbourCellParamList.numelt; ++l) {
rrc->neighbourConfiguration[l].neighbour_gNB_ID = *(NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_GNB_ID_IDX].uptr);
rrc->neighbourConfiguration[l].neighbour_nrcell_id = (uint64_t) *(NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_NR_CELLID_IDX].u64ptr);
rrc->neighbourConfiguration[l].physicalCellId = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_PHYSICAL_ID_IDX].uptr;
rrc->neighbourConfiguration[l].subcarrierSpacing = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_SCS_IDX].uptr;
rrc->neighbourConfiguration[l].absoluteFrequencySSB = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_ABS_FREQ_SSB_IDX].i64ptr;
rrc->neighbourConfiguration[l].neighbour_mcc = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_MCC_IDX].uptr;
rrc->neighbourConfiguration[l].neighbour_mnc = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_MNC_IDX].uptr;
rrc->neighbourConfiguration[l].neighbour_mnc_digit_length = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_MNC_DIGIT_LENGTH_IDX].uptr;
rrc->neighbourConfiguration[l].neighbour_tac = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_TAC_IDX].uptr;
}
rrc->number_of_neighbours = NeighbourCellParamList.numelt;
if (rrc->number_of_neighbours > 0) {
paramdef_t MeasurementEventParams[] = MEASUREMENT_EVENTS_GLOBALPARAMS_DESC;
paramlist_def_t MeasurementEventParamList = {GNB_CONFIG_STRING_MEASUREMENT_EVENTS, NULL, 0};
config_getlist(config_get_if(), &MeasurementEventParamList, MeasurementEventParams, sizeofArray(MeasurementEventParams), gnbpath);
rrc->measurementConfiguration.enableA2 = (*MeasurementEventParamList.paramarray[0][MEASUREMENT_EVENTS_ENABLE_A2_IDX].i64ptr);
if (rrc->measurementConfiguration.enableA2) {
rrc->measurementConfiguration.a2_threshold = *MeasurementEventParamList.paramarray[0][MEASUREMENT_EVENTS_ENABLE_A2_THRESHOLD_IDX].i64ptr;
rrc->measurementConfiguration.a2_time_to_trigger = *MeasurementEventParamList.paramarray[0][MEASUREMENT_EVENTS_ENABLE_A2_TIME_TO_TRIGGER_IDX].i64ptr;
}
rrc->measurementConfiguration.enableA3 = (*MeasurementEventParamList.paramarray[0][MEASUREMENT_EVENTS_ENABLE_A3_IDX].i64ptr);
if (rrc->measurementConfiguration.enableA3) {
rrc->measurementConfiguration.a3_offset = *MeasurementEventParamList.paramarray[0][MEASUREMENT_EVENTS_ENABLE_A3_OFFSET_IDX].i64ptr;
rrc->measurementConfiguration.a3_hysteresis = *MeasurementEventParamList.paramarray[0][MEASUREMENT_EVENTS_ENABLE_A3_HYSTERESIS_IDX].i64ptr;
rrc->measurementConfiguration.a3_time_to_trigger = *MeasurementEventParamList.paramarray[0][MEASUREMENT_EVENTS_ENABLE_A3_TIME_TO_TRIGGER_IDX].i64ptr;
}
}
paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC; paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC;
paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0}; paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
......
...@@ -229,6 +229,73 @@ typedef enum { ...@@ -229,6 +229,73 @@ typedef enum {
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Neighbour Cell Configurations*/
#define GNB_CONFIG_STRING_NEIGHBOUR_CELL_LIST "neighbour_cell_configuration"
#define GNB_CONFIG_STRING_NEIGHBOUR_GNB_ID "neighbour_gNB_ID"
#define GNB_CONFIG_STRING_NEIGHBOUR_NR_CELLID "neighbour_nr_cellid"
#define GNB_CONFIG_STRING_NEIGHBOUR_CELL_PHYSICAL_ID "neighbour_physical_cellId"
#define GNB_CONFIG_STRING_NEIGHBOUR_CELL_ABS_FREQ_SSB "neighbour_absoluteFrequencySSB"
#define GNB_CONFIG_STRING_NEIGHBOUR_CELL_SCS "neighbour_subcarrierSpacing"
#define GNB_CONFIG_STRING_NEIGHBOUR_MOBILE_COUNTRY_CODE "neighbour_mcc"
#define GNB_CONFIG_STRING_NEIGHBOUR_MOBILE_NETWORK_CODE "neighbour_mnc"
#define GNB_CONFIG_STRING_NEIGHBOUR_MNC_DIGIT_LENGTH "neighbour_mnc_length"
#define GNB_CONFIG_STRING_NEIGHBOUR_TRACKING_ARE_CODE "neighbour_tracking_area_code"
#define GNB_CONFIG_N_CELL_GNB_ID_IDX 0
#define GNB_CONFIG_N_CELL_NR_CELLID_IDX 1
#define GNB_CONFIG_N_CELL_PHYSICAL_ID_IDX 2
#define GNB_CONFIG_N_CELL_ABS_FREQ_SSB_IDX 3
#define GNB_CONFIG_N_CELL_SCS_IDX 4
#define GNB_CONFIG_N_CELL_MCC_IDX 5
#define GNB_CONFIG_N_CELL_MNC_IDX 6
#define GNB_CONFIG_N_CELL_MNC_DIGIT_LENGTH_IDX 7
#define GNB_CONFIG_N_CELL_TAC_IDX 8
#define GNBNEIGHBOURCELLPARAMS_DESC { \
/* optname helpstr paramflags XXXptr def val type numelt */ \
{GNB_CONFIG_STRING_GNB_ID, NULL, 0, .uptr=NULL, .defintval=0, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_NRCELLID, NULL, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \
{GNB_CONFIG_STRING_NEIGHBOUR_CELL_PHYSICAL_ID, "neighbour cell physical id", 0, .uptr=NULL, .defuintval=1000, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_NEIGHBOUR_CELL_ABS_FREQ_SSB, "neighbour cell abs freq ssb", 0, .i64ptr=NULL, .defint64val=621312, TYPE_INT64, 0}, \
{GNB_CONFIG_STRING_NEIGHBOUR_CELL_SCS, "neighbour cell scs", 0, .uptr=NULL, .defuintval=1, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_NEIGHBOUR_MOBILE_COUNTRY_CODE, "mobile country code", 0, .uptr=NULL, .defuintval=1000, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_NEIGHBOUR_MOBILE_NETWORK_CODE, "mobile network code", 0, .uptr=NULL, .defuintval=1000, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_NEIGHBOUR_MNC_DIGIT_LENGTH, "length of the MNC (2 or 3)", 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_NEIGHBOUR_TRACKING_ARE_CODE, NULL, 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
}
/* Measurement Event Configurations*/
#define GNB_CONFIG_STRING_MEASUREMENT_EVENTS "nr_measurement_event_configuration"
#define MEASUREMENT_EVENTS_ENABLE_A2 "enableA2"
#define MEASUREMENT_EVENTS_ENABLE_A3 "enableA3"
#define MEASUREMENT_EVENTS_ENABLE_A2_THRESHOLD "thresholdA2"
#define MEASUREMENT_EVENTS_ENABLE_A2_TIME_TO_TRIGGER "A2_timeToTrigger"
#define MEASUREMENT_EVENTS_ENABLE_A3_OFFSET "A3_offset"
#define MEASUREMENT_EVENTS_ENABLE_A3_HYSTERESIS "A3_hysteresis"
#define MEASUREMENT_EVENTS_ENABLE_A3_TIME_TO_TRIGGER "A3_timeToTrigger"
#define MEASUREMENT_EVENTS_GLOBALPARAMS_DESC { \
{MEASUREMENT_EVENTS_ENABLE_A2, "enabling a2 event", 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{MEASUREMENT_EVENTS_ENABLE_A3, "enabling a3 event", 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{MEASUREMENT_EVENTS_ENABLE_A2_THRESHOLD, "a2 threshold", 0, .i64ptr=NULL, .defint64val=30, TYPE_INT64, 0}, \
{MEASUREMENT_EVENTS_ENABLE_A2_TIME_TO_TRIGGER, "a2 time to trigger", 0, .i64ptr=NULL, .defint64val=1, TYPE_INT64, 0}, \
{MEASUREMENT_EVENTS_ENABLE_A3_OFFSET, "a3 offset", 0, .i64ptr=NULL, .defint64val=10, TYPE_INT64, 0}, \
{MEASUREMENT_EVENTS_ENABLE_A3_HYSTERESIS, "a3 hysteresis", 0, .i64ptr=NULL, .defint64val=0, TYPE_INT64, 0}, \
{MEASUREMENT_EVENTS_ENABLE_A3_TIME_TO_TRIGGER, "a3 time to trigger", 0, .i64ptr=NULL, .defint64val=1, TYPE_INT64, 0}, \
}
#define MEASUREMENT_EVENTS_ENABLE_A2_IDX 0
#define MEASUREMENT_EVENTS_ENABLE_A3_IDX 1
#define MEASUREMENT_EVENTS_ENABLE_A2_THRESHOLD_IDX 2
#define MEASUREMENT_EVENTS_ENABLE_A2_TIME_TO_TRIGGER_IDX 3
#define MEASUREMENT_EVENTS_ENABLE_A3_OFFSET_IDX 4
#define MEASUREMENT_EVENTS_ENABLE_A3_HYSTERESIS_IDX 5
#define MEASUREMENT_EVENTS_ENABLE_A3_TIME_TO_TRIGGER_IDX 6
/* PLMN ID configuration */ /* PLMN ID configuration */
#define GNB_CONFIG_STRING_PLMN_LIST "plmn_list" #define GNB_CONFIG_STRING_PLMN_LIST "plmn_list"
......
...@@ -1183,6 +1183,149 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t ssb_arfcn, int band, int scs) ...@@ -1183,6 +1183,149 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t ssb_arfcn, int band, int scs)
return mc; return mc;
} }
NR_MeasConfig_t *get_EventBasedMeasConfig(uint32_t ssb_arfcn, int band, int scs, const nr_measurement_event_configuration_t* measurementConfiguration, nr_neighbour_gnb_configuration_t* neighbourConfiguration, const int numberOfNeighbours){
bool intraFrequencyNeighbourExists = false;
LOG_D(NR_RRC, "HO LOG: Supports only Intra Frequency Meas with SCS:%d ABS ARFCN: %d\n", scs, ssb_arfcn);
for (uint8_t nCell = 0; nCell < numberOfNeighbours; nCell++){
nr_neighbour_gnb_configuration_t* neighbourCell = &neighbourConfiguration[nCell];
if (ssb_arfcn == neighbourCell->absoluteFrequencySSB && scs == neighbourCell->subcarrierSpacing) {
LOG_D(NR_RRC, "HO LOG: Intra Frequency Neighbour is Found!\n");
intraFrequencyNeighbourExists = true;
neighbourCell->intraFrequencyNeighbour = true;
}
}
if (!intraFrequencyNeighbourExists){
LOG_E(NR_RRC, "HO LOG: Currently Inter Frequency Measurements are not supported!\n");
return NULL;
}
NR_MeasConfig_t *mc = calloc(1, sizeof(*mc));
mc->measObjectToAddModList = calloc(1, sizeof(*mc->measObjectToAddModList));
mc->reportConfigToAddModList = calloc(1, sizeof(*mc->reportConfigToAddModList));
//A3 Configuration
NR_MeasObjectToAddMod_t *mo1 = calloc(1, sizeof(*mo1));
mo1->measObjectId = 1;
mo1->measObject.present = NR_MeasObjectToAddMod__measObject_PR_measObjectNR;
NR_MeasObjectNR_t *monr1 = calloc(1, sizeof(*monr1));
asn1cCallocOne(monr1->ssbFrequency, ssb_arfcn);
asn1cCallocOne(monr1->ssbSubcarrierSpacing, scs);
monr1->referenceSignalConfig.ssb_ConfigMobility = calloc(1, sizeof(*monr1->referenceSignalConfig.ssb_ConfigMobility));
monr1->referenceSignalConfig.ssb_ConfigMobility->deriveSSB_IndexFromCell = true;
monr1->absThreshSS_BlocksConsolidation = calloc(1, sizeof(*monr1->absThreshSS_BlocksConsolidation));
asn1cCallocOne(monr1->absThreshSS_BlocksConsolidation->thresholdRSRP, 36);
asn1cCallocOne(monr1->nrofSS_BlocksToAverage, 8);
monr1->smtc1 = calloc(1, sizeof(*monr1->smtc1));
monr1->smtc1->periodicityAndOffset.present = NR_SSB_MTC__periodicityAndOffset_PR_sf20;
monr1->smtc1->periodicityAndOffset.choice.sf20 = 2;
monr1->smtc1->duration = NR_SSB_MTC__duration_sf2;
monr1->quantityConfigIndex = 1;
monr1->ext1 = calloc(1, sizeof(*monr1->ext1));
asn1cCallocOne(monr1->ext1->freqBandIndicatorNR, band);
for (uint8_t nCell = 0; nCell < numberOfNeighbours; nCell++){
const nr_neighbour_gnb_configuration_t* neighbourCell = &neighbourConfiguration[nCell];
if (!neighbourCell->intraFrequencyNeighbour)
continue;
LOG_D(NR_RRC, "HO LOG: Preparing Meas Config for neighbour Cell with the ID: %d\n", neighbourCell->physicalCellId);
if (monr1->cellsToAddModList == NULL) {
monr1->cellsToAddModList = calloc(1, sizeof(*monr1->cellsToAddModList));
}
NR_CellsToAddMod_t *cell = calloc(1, sizeof(*cell));
cell->physCellId = neighbourCell->physicalCellId;
ASN_SEQUENCE_ADD(&monr1->cellsToAddModList->list, cell);
}
const int numIntraFreqNeighbours = monr1->cellsToAddModList->list.count;
mo1->measObject.choice.measObjectNR = monr1;
asn1cSeqAdd(&mc->measObjectToAddModList->list, mo1);
NR_ReportConfigToAddMod_t *rc_A3 = calloc(1, sizeof(*rc_A3));
rc_A3->reportConfigId = 1;
rc_A3->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
NR_EventTriggerConfig_t *etrc_A3 = calloc(1, sizeof(*etrc_A3));
etrc_A3->eventId.present = NR_EventTriggerConfig__eventId_PR_eventA3;
etrc_A3->eventId.choice.eventA3 = calloc(1, sizeof(*etrc_A3->eventId.choice.eventA3));
etrc_A3->eventId.choice.eventA3->a3_Offset.present = NR_MeasTriggerQuantityOffset_PR_rsrp;
etrc_A3->eventId.choice.eventA3->a3_Offset.choice.rsrp = measurementConfiguration->a3_offset;
etrc_A3->eventId.choice.eventA3->reportOnLeave = true;
etrc_A3->eventId.choice.eventA3->hysteresis = measurementConfiguration->a3_hysteresis;
etrc_A3->eventId.choice.eventA3->timeToTrigger = measurementConfiguration->a3_time_to_trigger;
etrc_A3->rsType = NR_NR_RS_Type_ssb;
etrc_A3->reportInterval = NR_ReportInterval_ms1024;
etrc_A3->reportAmount = NR_EventTriggerConfig__reportAmount_r4;
etrc_A3->reportQuantityCell.rsrp = true;
etrc_A3->reportQuantityCell.rsrq = false;
etrc_A3->reportQuantityCell.sinr = true;
asn1cCallocOne(etrc_A3->maxNrofRS_IndexesToReport, 4);
etrc_A3->maxReportCells = numIntraFreqNeighbours;
etrc_A3->includeBeamMeasurements = false;
NR_ReportConfigNR_t *rcnr_A3 = calloc(1, sizeof(*rcnr_A3));
rcnr_A3->reportType.present = NR_ReportConfigNR__reportType_PR_eventTriggered;
rcnr_A3->reportType.choice.eventTriggered = etrc_A3;
rc_A3->reportConfig.choice.reportConfigNR = rcnr_A3;
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_A3);
mc->measIdToAddModList = calloc(1, sizeof(*mc->measIdToAddModList));
NR_MeasIdToAddMod_t *measid_A3 = calloc(1, sizeof(*measid_A3));
measid_A3->measId = 1;
measid_A3->measObjectId = 1;
measid_A3->reportConfigId = 1;
asn1cSeqAdd(&mc->measIdToAddModList->list, measid_A3);
// A2 Report Configuration
if (measurementConfiguration->enableA2) {
LOG_D(NR_RRC, "HO LOG: Preparing A2 Event Measurement Configuration!\n");
NR_ReportConfigToAddMod_t *rc_A2 = calloc(1, sizeof(*rc_A2));
rc_A2->reportConfigId = 2;
rc_A2->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
NR_EventTriggerConfig_t *etrc_A2 = calloc(1, sizeof(*etrc_A2));
etrc_A2->eventId.present = NR_EventTriggerConfig__eventId_PR_eventA2;
etrc_A2->eventId.choice.eventA2 = calloc(1, sizeof(*etrc_A2->eventId.choice.eventA2));
etrc_A2->eventId.choice.eventA2->a2_Threshold.present = NR_MeasTriggerQuantity_PR_rsrp;
etrc_A2->eventId.choice.eventA2->a2_Threshold.choice.rsrp = measurementConfiguration->a2_threshold;
etrc_A2->eventId.choice.eventA2->reportOnLeave = false;
etrc_A2->eventId.choice.eventA2->hysteresis = 0;
etrc_A2->eventId.choice.eventA2->timeToTrigger = measurementConfiguration->a2_time_to_trigger;
etrc_A2->rsType = NR_NR_RS_Type_ssb;
etrc_A2->reportInterval = NR_ReportInterval_ms480;
etrc_A2->reportAmount = NR_EventTriggerConfig__reportAmount_r4;
etrc_A2->reportQuantityCell.rsrp = true;
etrc_A2->reportQuantityCell.rsrq = false;
etrc_A2->reportQuantityCell.sinr = false;
asn1cCallocOne(etrc_A2->maxNrofRS_IndexesToReport, 4);
etrc_A2->maxReportCells = 1;
etrc_A2->includeBeamMeasurements = false;
NR_ReportConfigNR_t *rcnr_A2 = calloc(1, sizeof(*rcnr_A2));
rcnr_A2->reportType.present = NR_ReportConfigNR__reportType_PR_eventTriggered;
rcnr_A2->reportType.choice.eventTriggered = etrc_A2;
rc_A2->reportConfig.choice.reportConfigNR = rcnr_A2;
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_A2);
NR_MeasIdToAddMod_t *measid_A2 = calloc(1, sizeof(*measid_A2));
measid_A2->measId = 2;
measid_A2->measObjectId = 1;
measid_A2->reportConfigId = 2;
asn1cSeqAdd(&mc->measIdToAddModList->list, measid_A2);
}
mc->quantityConfig = calloc(1, sizeof(*mc->quantityConfig));
mc->quantityConfig->quantityConfigNR_List = calloc(1, sizeof(*mc->quantityConfig->quantityConfigNR_List));
NR_QuantityConfigNR_t *qcnr3 = calloc(1, sizeof(*qcnr3));
asn1cCallocOne(qcnr3->quantityConfigCell.ssb_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
asn1cCallocOne(qcnr3->quantityConfigCell.csi_RS_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
asn1cSeqAdd(&mc->quantityConfig->quantityConfigNR_List->list, qcnr3);
return mc;
}
void free_defaultMeasConfig(NR_MeasConfig_t *mc) void free_defaultMeasConfig(NR_MeasConfig_t *mc)
{ {
ASN_STRUCT_FREE(asn_DEF_NR_MeasConfig, mc); ASN_STRUCT_FREE(asn_DEF_NR_MeasConfig, mc);
......
...@@ -143,6 +143,7 @@ int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP, ...@@ -143,6 +143,7 @@ int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP,
int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t rrc_TransactionIdentifier); int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t rrc_TransactionIdentifier);
NR_MeasConfig_t *get_defaultMeasConfig(uint32_t absFreqSSB, int band, int scs); NR_MeasConfig_t *get_defaultMeasConfig(uint32_t absFreqSSB, int band, int scs);
NR_MeasConfig_t *get_EventBasedMeasConfig(uint32_t ssb_arfcn, int band, int scs, const nr_measurement_event_configuration_t* measurementConfiguration, nr_neighbour_gnb_configuration_t* neighbourConfiguration, const int numberOfNeighbours);
void free_defaultMeasConfig(NR_MeasConfig_t *mc); void free_defaultMeasConfig(NR_MeasConfig_t *mc);
uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi); uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
......
...@@ -96,6 +96,8 @@ ...@@ -96,6 +96,8 @@
#define NR_UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! #define NR_UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!!
#define NR_UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1 #define NR_UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1
#define MAX_NUMBER_OF_NEIGHBOUR_GNBS 6
typedef enum { typedef enum {
NR_RRC_OK=0, NR_RRC_OK=0,
NR_RRC_ConnSetup_failed, NR_RRC_ConnSetup_failed,
...@@ -343,6 +345,30 @@ typedef struct { ...@@ -343,6 +345,30 @@ typedef struct {
int do_drb_integrity; int do_drb_integrity;
} nr_security_configuration_t; } nr_security_configuration_t;
typedef struct {
uint32_t neighbour_gNB_ID;
uint64_t neighbour_nrcell_id;
int physicalCellId;
int absoluteFrequencySSB;
int subcarrierSpacing;
uint16_t neighbour_mcc;
uint16_t neighbour_mnc;
uint8_t neighbour_mnc_digit_length;
uint32_t neighbour_tac;
bool intraFrequencyNeighbour;
} nr_neighbour_gnb_configuration_t;
typedef struct {
int enableA2;
int enableA3;
int a2_threshold;
int a2_time_to_trigger;
int a3_offset;
int a3_hysteresis;
int a3_time_to_trigger;
} nr_measurement_event_configuration_t;
typedef struct nr_mac_rrc_dl_if_s { typedef struct nr_mac_rrc_dl_if_s {
f1_setup_response_func_t f1_setup_response; f1_setup_response_func_t f1_setup_response;
f1_setup_failure_func_t f1_setup_failure; f1_setup_failure_func_t f1_setup_failure;
...@@ -405,6 +431,9 @@ typedef struct gNB_RRC_INST_s { ...@@ -405,6 +431,9 @@ typedef struct gNB_RRC_INST_s {
nr_mac_rrc_dl_if_t mac_rrc; nr_mac_rrc_dl_if_t mac_rrc;
cucp_cuup_if_t cucp_cuup; cucp_cuup_if_t cucp_cuup;
nr_neighbour_gnb_configuration_t neighbourConfiguration[MAX_NUMBER_OF_NEIGHBOUR_GNBS];
nr_measurement_event_configuration_t measurementConfiguration;
uint8_t number_of_neighbours;
RB_HEAD(rrc_du_tree, nr_rrc_du_container_t) dus; // DUs, indexed by assoc_id RB_HEAD(rrc_du_tree, nr_rrc_du_container_t) dus; // DUs, indexed by assoc_id
size_t num_dus; size_t num_dus;
......
...@@ -510,6 +510,16 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p ...@@ -510,6 +510,16 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p
#endif #endif
} }
static void clone_MeasConfig(const NR_MeasConfig_t *orig, rrc_gNB_ue_context_t *ue_context_pP)
{
uint8_t buf[16636];
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MeasConfig, NULL, orig, buf, sizeof(buf));
AssertFatal(enc_rval.encoded > 0, "could not clone Meas Config: problem while encoding\n");
asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_MeasConfig, (void **)&ue_context_pP->ue_context.measConfig, buf, enc_rval.encoded, 0, 0);
AssertFatal(dec_rval.code == RC_OK && dec_rval.consumed == enc_rval.encoded,
"could not clone NR_MeasConfig_t: problem while decodung\n");
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -555,11 +565,26 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co ...@@ -555,11 +565,26 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
/* we cannot calculate the default measurement config without MIB&SIB1, as /* we cannot calculate the default measurement config without MIB&SIB1, as
* we don't know the DU's SSB ARFCN */ * we don't know the DU's SSB ARFCN */
uint32_t ssb_arfcn = get_ssb_arfcn(cell_info, du->mib, du->sib1); uint32_t ssb_arfcn = get_ssb_arfcn(cell_info, du->mib, du->sib1);
measconfig = get_defaultMeasConfig(ssb_arfcn, band, scs); if (rrc->measurementConfiguration.enableA3 && rrc->number_of_neighbours > 0) {
LOG_D(NR_RRC, "HO LOG: Event Based Measurement is Selected!\n");
measconfig = get_EventBasedMeasConfig(ssb_arfcn, band, scs, &(rrc->measurementConfiguration), rrc->neighbourConfiguration, rrc->number_of_neighbours);
} else{
measconfig = get_defaultMeasConfig(ssb_arfcn, band, scs);
}
}
if (ue_p->measConfig != NULL) {
free(ue_p->measConfig);
ue_p->measConfig = NULL;
} }
if (measconfig != NULL)
clone_MeasConfig(measconfig, ue_context_pP);
NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false);
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false); NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false);
uint8_t buffer[RRC_BUF_SIZE] = {0}; uint8_t buffer[RRC_BUF_SIZE] = {0};
int size = do_RRCReconfiguration(ue_p, int size = do_RRCReconfiguration(ue_p,
buffer, buffer,
...@@ -1204,22 +1229,120 @@ fallback_rrc_setup: ...@@ -1204,22 +1229,120 @@ fallback_rrc_setup:
static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport) static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport)
{ {
LOG_D(NR_RRC, "Process Measurement Report\n");
if (LOG_DEBUGFLAG(DEBUG_ASN1)) if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_MeasurementReport, (void *)measurementReport); xer_fprint(stdout, &asn_DEF_NR_MeasurementReport, (void *)measurementReport);
DevAssert(measurementReport->criticalExtensions.present == NR_MeasurementReport__criticalExtensions_PR_measurementReport DevAssert(measurementReport->criticalExtensions.present == NR_MeasurementReport__criticalExtensions_PR_measurementReport
&& measurementReport->criticalExtensions.choice.measurementReport != NULL); && measurementReport->criticalExtensions.choice.measurementReport != NULL);
gNB_RRC_UE_t *ue_ctxt = &ue_context->ue_context; gNB_RRC_UE_t *ue_ctxt = &ue_context->ue_context;
ASN_STRUCT_FREE(asn_DEF_NR_MeasResults, ue_ctxt->measResults); NR_MeasConfig_t *meas_config = ue_ctxt->measConfig;
ue_ctxt->measResults = NULL; if (meas_config == NULL) {
LOG_E(NR_RRC, "%s: %i - meas_config = %p\n", __FUNCTION__, __LINE__, meas_config);
return;
}
// xer_fprint(stdout, &asn_DEF_NR_MeasurementReport, (void *)measurementReport);
// xer_fprint(stdout, &asn_DEF_NR_MeasConfig, (void*)ue_ctxt->measConfig);
NR_MeasurementReport_IEs_t *measurementReport_IEs = measurementReport->criticalExtensions.choice.measurementReport;
const NR_MeasId_t measId = measurementReport_IEs->measResults.measId;
NR_MeasIdToAddMod_t *meas_id_s = NULL;
for (int meas_idx = 0; meas_idx < meas_config->measIdToAddModList->list.count; meas_idx++) {
if (measId == meas_config->measIdToAddModList->list.array[meas_idx]->measId) {
meas_id_s = meas_config->measIdToAddModList->list.array[meas_idx];
break;
}
}
if (meas_id_s == NULL){
LOG_E(NR_RRC, "Incoming Meas ID with id: %d Can not Found!\n", (int)measId);
return;
}
LOG_D(NR_RRC, "HO LOG: Meas Id is found: %d\n", (int)meas_id_s->measId);
struct NR_ReportConfigToAddMod__reportConfig *report_config = NULL;
for (int rep_id = 0; rep_id < meas_config->reportConfigToAddModList->list.count; rep_id++) {
if (meas_id_s->reportConfigId == meas_config->reportConfigToAddModList->list.array[rep_id]->reportConfigId) {
report_config = &meas_config->reportConfigToAddModList->list.array[rep_id]->reportConfig;
}
}
if (report_config == NULL) {
LOG_E(NR_RRC, "There is no related report configuration for this measId!\n");
return;
}
if (report_config->choice.reportConfigNR->reportType.present == NR_ReportConfigNR__reportType_PR_periodical){
LOG_I(NR_RRC, "Periodical Event Report! Do Nothing for now...\n");
ASN_STRUCT_FREE(asn_DEF_NR_MeasResults, ue_ctxt->measResults);
ue_ctxt->measResults = NULL;
const NR_MeasId_t id = measurementReport->criticalExtensions.choice.measurementReport->measResults.measId;
AssertFatal(id, "unexpected MeasResult for MeasurementId %ld received\n", id);
asn1cCallocOne(ue_ctxt->measResults, measurementReport->criticalExtensions.choice.measurementReport->measResults);
/* we "keep" the measurement report, so set to 0 */
free(measurementReport->criticalExtensions.choice.measurementReport);
measurementReport->criticalExtensions.choice.measurementReport = NULL;
return;
}
if (report_config->choice.reportConfigNR->reportType.present != NR_ReportConfigNR__reportType_PR_eventTriggered){
LOG_D(NR_RRC, "Incoming Report Type: %d is not supported! \n", report_config->choice.reportConfigNR->reportType.present);
return;
}
NR_EventTriggerConfig_t *event_triggered = report_config->choice.reportConfigNR->reportType.choice.eventTriggered;
LOG_I(NR_RRC, "HO LOG: Incoming Report Id: %d\n", (int)measId);
int servingCellRSRP = 0;
int neighbourCellRSRP = 0;
switch (event_triggered->eventId.present) {
case NR_EventTriggerConfig__eventId_PR_eventA2:
LOG_I(NR_RRC, "\nHO LOG: Event A2 (Serving becomes worse than threshold)\n");
break;
case NR_EventTriggerConfig__eventId_PR_eventA3:
{
LOG_I(NR_RRC, "\nHO LOG: Event A3 Report - Neighbour Becomes Better than Serving!\n");
for (int serving_cell_idx = 0; serving_cell_idx < measurementReport->criticalExtensions.choice.measurementReport->measResults.measResultServingMOList.list.count; serving_cell_idx++) {
const NR_MeasResultServMO_t* meas_result_serv_MO = measurementReport->criticalExtensions.choice.measurementReport->measResults.measResultServingMOList.list.array[serving_cell_idx];
if (meas_result_serv_MO->measResultServingCell.measResult.cellResults.resultsSSB_Cell) {
servingCellRSRP = *(meas_result_serv_MO->measResultServingCell.measResult.cellResults.resultsSSB_Cell->rsrp) - 157;
} else {
servingCellRSRP = *(meas_result_serv_MO->measResultServingCell.measResult.cellResults.resultsCSI_RS_Cell->rsrp) - 157;
}
LOG_D(NR_RRC, "Serving Cell RSRP: %d\n", servingCellRSRP);
}
//Only Meas Result NR is supported at the moment
if (measurementReport->criticalExtensions.choice.measurementReport->measResults.measResultNeighCells == NULL)
break;
if (measurementReport->criticalExtensions.choice.measurementReport->measResults.measResultNeighCells->present != NR_MeasResults__measResultNeighCells_PR_measResultListNR)
break;
const NR_MeasId_t id = measurementReport->criticalExtensions.choice.measurementReport->measResults.measId; for (int neigh_meas_idx = 0; neigh_meas_idx < measurementReport->criticalExtensions.choice.measurementReport->measResults.measResultNeighCells->choice.measResultListNR->list.count; neigh_meas_idx++){
AssertFatal(id, "unexpected MeasResult for MeasurementId %ld received\n", id); const NR_MeasResultNR_t* meas_result_neigh_cell = (measurementReport->criticalExtensions.choice.measurementReport->measResults.measResultNeighCells->choice.measResultListNR->list.array[neigh_meas_idx]);
asn1cCallocOne(ue_ctxt->measResults, measurementReport->criticalExtensions.choice.measurementReport->measResults); const int neighbourCellId = *(meas_result_neigh_cell->physCellId);
/* we "keep" the measurement report, so set to 0 */ if (meas_result_neigh_cell->measResult.cellResults.resultsSSB_Cell) {
free(measurementReport->criticalExtensions.choice.measurementReport); neighbourCellRSRP = *(meas_result_neigh_cell->measResult.cellResults.resultsSSB_Cell->rsrp) - 157;
measurementReport->criticalExtensions.choice.measurementReport = NULL; } else {
neighbourCellRSRP = *(meas_result_neigh_cell->measResult.cellResults.resultsCSI_RS_Cell->rsrp) - 157;
}
LOG_I(NR_RRC, "HO LOG: Measurement Report has came for the neighbour: %d with RSRP: %d\n", neighbourCellId, neighbourCellRSRP);
}
}
break;
default:
LOG_D(NR_RRC, "NR_EventTriggerConfig__eventId_PR_NOTHING or Other event report\n");
break;
}
} }
static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment