From a3ddabafc62ab8a7dc3b7e0a6568ba8f6572fd13 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 27 Jul 2023 15:41:37 +0200 Subject: [PATCH 01/47] Use cmake3 command if on RHEL --- cmake_targets/tools/build_helper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 22905e1a3b..9b643ab16e 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -32,7 +32,7 @@ OS_DISTRO=$(grep "^ID=" /etc/os-release | sed "s/ID=//" | sed "s/\"//g") OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed "s/\"//g") case "$OS_DISTRO" in fedora) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;; - rhel) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;; + rhel) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake3" ;; rocky) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;; centos) OS_BASEDISTRO="centos"; INSTALLER="yum"; CMAKE="cmake3" ;; debian) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;; From 3161add2c12f4997ba7b19f8e7bb30469be522ea Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 28 Jul 2023 11:21:38 +0200 Subject: [PATCH 02/47] build_oai/build_helper: use $CMAKE Some distributions, e.g., CentOS8 or RHEL8, ship with an old cmake (v2.8). To provide a newer, they have a separate cmake3 package, where a recent cmake version is in program cmake3. To be agnostic, build_helper detects the distribution and choses the cmake program to use. This commit uses the correct cmake, which is provided in the environment variable $CMAKE. --- cmake_targets/build_oai | 2 +- cmake_targets/tools/build_helper | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index cb66d4f862..687431db37 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -523,7 +523,7 @@ function main() { echo_info "Doxygen generation log is located here: $doxygen_log" echo_info "Generating Doxygen files....please wait" ( - cmake --build . --target doc + $CMAKE --build . --target doc ) >& $doxygen_log fi diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 9b643ab16e..4f1ea858a4 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -226,11 +226,11 @@ compilations() { local verbose=$([ "$VERBOSE_COMPILE" == "1" ] && echo "-v" || echo "") echo cd $OPENAIR_DIR/cmake_targets/$dir/build cd $OPENAIR_DIR/cmake_targets/$dir/build - echo_info "Running \"cmake --build . $verbose --target $targets -- -j$(nproc)\"" $green + echo_info "Running \"$CMAKE --build . $verbose --target $targets -- -j$(nproc)\"" $green echo "Log file for compilation is being written to: $dlog/$logfile" set +e { - cmake --build . $verbose --target $targets -- -j$(nproc) + $CMAKE --build . $verbose --target $targets -- -j$(nproc) ret=$? } > $dlog/$logfile 2>&1 if [ "$VERBOSE_CI" == "1" ]; then From 9b8a8280ad00943ba14c6f6d12e021d023ad977a Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 18 Apr 2023 16:00:35 +0200 Subject: [PATCH 03/47] handle TDD pattern2 at UE --- executables/nr-ue.c | 34 +++---- .../nfapi/public_inc/fapi_nr_ue_interface.h | 6 +- openair1/SCHED_NR_UE/phy_frame_config_nr.h | 2 +- openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c | 77 ++++++--------- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 2 +- openair2/LAYER2/NR_MAC_UE/config_ue.c | 94 +++++++++---------- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 4 - 7 files changed, 94 insertions(+), 125 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 8b1f6b969f..ca73bfcc01 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -496,8 +496,9 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) { UE_nr_rxtx_proc_t *proc = &rxtxD->proc; void *txp[NB_ANTENNAS_TX]; - for (int i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void *)&UE->common_vars.txData[i][UE->frame_parms.get_samples_slot_timestamp(proc->nr_slot_tx, &UE->frame_parms, 0)]; + int slot = proc->nr_slot_tx; + for (int i = 0; i < UE->frame_parms.nb_antennas_tx; i++) + txp[i] = (void *)&UE->common_vars.txData[i][UE->frame_parms.get_samples_slot_timestamp(slot, &UE->frame_parms, 0)]; radio_tx_burst_flag_t flags = TX_BURST_INVALID; @@ -506,19 +507,18 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) { openair0_cfg[0].duplex_mode == duplex_mode_TDD && !get_softmodem_params()->continuous_tx) { - uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots; - int nrofUplinkSlots = mac->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - int nrofUplinkSymbols = mac->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols; - int slot_tx_usrp = proc->nr_slot_tx; - uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSymbols != 0); - uint8_t first_tx_slot = tdd_period - num_UL_slots; - - if (slot_tx_usrp % tdd_period == first_tx_slot) - flags = TX_BURST_START; - else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1) - flags = TX_BURST_END; - else if (slot_tx_usrp % tdd_period > first_tx_slot) - flags = TX_BURST_MIDDLE; + int slots_frame = UE->frame_parms.slots_per_frame; + int curr_slot = nr_ue_slot_select(&UE->nrUE_config, slot); + if (curr_slot != NR_DOWNLINK_SLOT) { + int next_slot = nr_ue_slot_select(&UE->nrUE_config, (slot + 1) % slots_frame); + int prev_slot = nr_ue_slot_select(&UE->nrUE_config, (slot + slots_frame - 1) % slots_frame); + if (prev_slot == NR_DOWNLINK_SLOT) + flags = TX_BURST_START; + else if (next_slot == NR_DOWNLINK_SLOT) + flags = TX_BURST_END; + else + flags = TX_BURST_MIDDLE; + } } else { flags = TX_BURST_MIDDLE; } @@ -851,8 +851,8 @@ void *UE_thread(void *arg) curMsg.proc.frame_rx = (absolute_slot / nb_slot_frame) % MAX_FRAME_NUMBER; curMsg.proc.frame_tx = ((absolute_slot + DURATION_RX_TO_TX) / nb_slot_frame) % MAX_FRAME_NUMBER; if (mac->phy_config_request_sent) { - curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx); - curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx); + curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.nr_slot_rx); + curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.nr_slot_tx); } else { curMsg.proc.rx_slot_type = NR_DOWNLINK_SLOT; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 4acd5e0d5f..1220293e12 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -636,13 +636,12 @@ typedef struct typedef struct { - fapi_nr_max_num_of_symbol_per_slot_t* max_num_of_symbol_per_slot_list; + fapi_nr_max_num_of_symbol_per_slot_t *max_num_of_symbol_per_slot_list; } fapi_nr_max_tdd_periodicity_t; typedef struct { - uint8_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4 uint8_t tdd_period_in_slots; fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list; @@ -683,7 +682,8 @@ typedef struct { fapi_nr_cell_config_t cell_config; fapi_nr_ssb_config_t ssb_config; fapi_nr_ssb_table_t ssb_table; - fapi_nr_tdd_table_t tdd_table; + fapi_nr_tdd_table_t tdd_table_1; + fapi_nr_tdd_table_t *tdd_table_2; fapi_nr_prach_config_t prach_config; } fapi_nr_config_request_t; diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr.h b/openair1/SCHED_NR_UE/phy_frame_config_nr.h index fcc2fa5838..59df0ba959 100644 --- a/openair1/SCHED_NR_UE/phy_frame_config_nr.h +++ b/openair1/SCHED_NR_UE/phy_frame_config_nr.h @@ -72,7 +72,7 @@ int slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_slot); * @param nr_slot : slot number @returns int : downlink, uplink or mixed slot type */ -int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_slot); +int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_slot); /** \brief This function frees tdd configuration for nr * @param frame_parms NR DL Frame parameters diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c index 696828a970..be1f39ab67 100644 --- a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c @@ -39,63 +39,40 @@ * *********************************************************************/ -int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_slot) { - /* for FFD all slot can be considered as an uplink */ - int mu = cfg->ssb_config.scs_common, check_slot = 0; +int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_slot) +{ + if (cfg->cell_config.frame_duplex_type == FDD) + return NR_UPLINK_SLOT | NR_DOWNLINK_SLOT; - if (cfg->cell_config.frame_duplex_type == FDD) { - return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT); + int period = cfg->tdd_table_1.tdd_period_in_slots + + (cfg->tdd_table_2 ? cfg->tdd_table_2->tdd_period_in_slots : 0); + int rel_slot = nr_slot % period; + fapi_nr_tdd_table_t *tdd_table = &cfg->tdd_table_1; + if (cfg->tdd_table_2 && rel_slot >= tdd_table->tdd_period_in_slots) { + rel_slot -= tdd_table->tdd_period_in_slots; + tdd_table = cfg->tdd_table_2; } - if (cfg->tdd_table.max_tdd_periodicity_list == NULL) // this happens before receiving TDD configuration - return (NR_DOWNLINK_SLOT); - if (nr_frame%2 == 0) { - for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) { - check_slot++; - } - } + if (tdd_table->max_tdd_periodicity_list == NULL) // this happens before receiving TDD configuration + return NR_DOWNLINK_SLOT; - if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) { - return (NR_UPLINK_SLOT); - } + fapi_nr_max_tdd_periodicity_t *current_slot = &tdd_table->max_tdd_periodicity_list[rel_slot]; - check_slot = 0; + // if the 1st symbol is UL the whole slot is UL + if (current_slot->max_num_of_symbol_per_slot_list[0].slot_config == 1) + return NR_UPLINK_SLOT; - for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) { - check_slot++; - } - } + // if the 1st symbol is flexible the whole slot is mixed + if (current_slot->max_num_of_symbol_per_slot_list[0].slot_config == 2) + return NR_MIXED_SLOT; - if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) { - return (NR_DOWNLINK_SLOT); - } else { - return (NR_MIXED_SLOT); - } - } else { - for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<max_num_of_symbol_per_slot_list[i].slot_config != 0) { + return NR_MIXED_SLOT; } } + + // if here, all the symbols where DL + return NR_DOWNLINK_SLOT; } diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index e7b6259284..0067c546ba 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -3635,7 +3635,7 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig, long transformPrec int tdd_period_to_num[8] = {500,625,1000,1250,2000,2500,5000,10000}; -bool is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slot_t slot) +bool is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slot) { if (tdd_UL_DL_ConfigurationCommon == NULL) return true; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 8798213b4c..da26cae863 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -39,21 +39,19 @@ #include "executables/softmodem-common.h" #include "SCHED_NR/phy_frame_config_nr.h" -void set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, +void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table, int mu, - NR_TDD_UL_DL_ConfigCommon_t *tdd_config) { + NR_TDD_UL_DL_Pattern_t *pattern) +{ + const int nrofDownlinkSlots = pattern->nrofDownlinkSlots; + const int nrofDownlinkSymbols = pattern->nrofDownlinkSymbols; + const int nrofUplinkSlots = pattern->nrofUplinkSlots; + const int nrofUplinkSymbols = pattern->nrofUplinkSymbols; + const int nb_periods_per_frame = get_nb_periods_per_frame(pattern->dl_UL_TransmissionPeriodicity); + const int nb_slots_per_period = ((1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) / nb_periods_per_frame; + tdd_table->tdd_period_in_slots = nb_slots_per_period; - const int nrofDownlinkSlots = tdd_config->pattern1.nrofDownlinkSlots; - const int nrofDownlinkSymbols = tdd_config->pattern1.nrofDownlinkSymbols; - const int nrofUplinkSlots = tdd_config->pattern1.nrofUplinkSlots; - const int nrofUplinkSymbols = tdd_config->pattern1.nrofUplinkSymbols; - int slot_number = 0; - const int nb_periods_per_frame = get_nb_periods_per_frame(tdd_config->pattern1.dl_UL_TransmissionPeriodicity); - const int nb_slots_to_set = TDD_CONFIG_NB_FRAMES*(1<tdd_table.tdd_period_in_slots = nb_slots_per_period; - - if ( (nrofDownlinkSymbols + nrofUplinkSymbols) == 0 ) + if ((nrofDownlinkSymbols + nrofUplinkSymbols) == 0) AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots), "set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, nrofUplinkSlots %d, nb_slots_per_period %d \n", nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period); @@ -64,57 +62,43 @@ void set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period); } - cfg->tdd_table.max_tdd_periodicity_list = (fapi_nr_max_tdd_periodicity_t *) malloc(nb_slots_to_set*sizeof(fapi_nr_max_tdd_periodicity_t)); + tdd_table->max_tdd_periodicity_list = (fapi_nr_max_tdd_periodicity_t *) malloc(nb_slots_per_period * sizeof(fapi_nr_max_tdd_periodicity_t)); - for(int memory_alloc =0 ; memory_alloctdd_table.max_tdd_periodicity_list[memory_alloc].max_num_of_symbol_per_slot_list = (fapi_nr_max_num_of_symbol_per_slot_t *) malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT*sizeof( - fapi_nr_max_num_of_symbol_per_slot_t)); + for(int memory_alloc = 0 ; memory_alloc < nb_slots_per_period; memory_alloc++) + tdd_table->max_tdd_periodicity_list[memory_alloc].max_num_of_symbol_per_slot_list = + (fapi_nr_max_num_of_symbol_per_slot_t *) malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT*sizeof(fapi_nr_max_num_of_symbol_per_slot_t)); - while(slot_number != nb_slots_to_set) { + int slot_number = 0; + while(slot_number != nb_slots_per_period) { if(nrofDownlinkSlots != 0) { - for (int number_of_symbol = 0; number_of_symbol < nrofDownlinkSlots*NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { - cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config= 0; - - if((number_of_symbol+1)%NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) + for (int number_of_symbol = 0; number_of_symbol < nrofDownlinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { + tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol % NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config = 0; + if((number_of_symbol + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) slot_number++; } } if (nrofDownlinkSymbols != 0 || nrofUplinkSymbols != 0) { - for(int number_of_symbol =0; number_of_symbol < nrofDownlinkSymbols; number_of_symbol++) { - cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config= 0; + for(int number_of_symbol = 0; number_of_symbol < nrofDownlinkSymbols; number_of_symbol++) { + tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 0; } - - for(int number_of_symbol = nrofDownlinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT-nrofUplinkSymbols; number_of_symbol++) { - cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config= 2; + for(int number_of_symbol = nrofDownlinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol++) { + tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 2; } - - for(int number_of_symbol = NR_NUMBER_OF_SYMBOLS_PER_SLOT-nrofUplinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { - cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config= 1; + for(int number_of_symbol = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { + tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 1; } - slot_number++; } if(nrofUplinkSlots != 0) { - for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots*NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { - cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config= 1; - - if((number_of_symbol+1)%NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) + for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { + tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config = 1; + if((number_of_symbol + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) slot_number++; } } } - - if (tdd_config->pattern1.ext1 == NULL) { - cfg->tdd_table.tdd_period = tdd_config->pattern1.dl_UL_TransmissionPeriodicity; - } else { - AssertFatal(tdd_config->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL, "scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n"); - cfg->tdd_table.tdd_period = *tdd_config->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530; - } - - LOG_I(NR_MAC, "TDD has been properly configured\n"); - } void config_common_ue_sa(NR_UE_MAC_INST_t *mac, @@ -204,9 +188,15 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, // TDD Table Configuration if (cfg->cell_config.frame_duplex_type == TDD){ - set_tdd_config_nr_ue(cfg, + set_tdd_config_nr_ue(&cfg->tdd_table_1, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - mac->tdd_UL_DL_ConfigurationCommon); + &mac->tdd_UL_DL_ConfigurationCommon->pattern1); + if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) { + cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t)); + set_tdd_config_nr_ue(cfg->tdd_table_2, + frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + mac->tdd_UL_DL_ConfigurationCommon->pattern2); + } } // PRACH configuration @@ -375,9 +365,15 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, // TDD Table Configuration if (cfg->cell_config.frame_duplex_type == TDD){ - set_tdd_config_nr_ue(cfg, + set_tdd_config_nr_ue(&cfg->tdd_table_1, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - mac->tdd_UL_DL_ConfigurationCommon); + &mac->tdd_UL_DL_ConfigurationCommon->pattern1); + if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) { + cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t)); + set_tdd_config_nr_ue(cfg->tdd_table_2, + frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + mac->tdd_UL_DL_ConfigurationCommon->pattern2); + } } // PRACH configuration diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 5534e586b1..2259ae7cf1 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -246,10 +246,6 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, uint8_t *ulsch_buffer, uint16_t buflen); -void set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, - int mu, - NR_TDD_UL_DL_ConfigCommon_t *tdd_config); - void set_harq_status(NR_UE_MAC_INST_t *mac, uint8_t pucch_id, uint8_t harq_id, From 6979b56aa792bfabb8f9d98ffd8c7b98edf67dce Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 6 Jul 2023 10:01:20 +0200 Subject: [PATCH 04/47] Scheduler lock: provide additional info on failure --- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 4e30c74a5c..b774ab6c72 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -46,19 +46,19 @@ #define NR_SCHED_LOCK(lock) \ do { \ int rc = pthread_mutex_lock(lock); \ - AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \ + AssertFatal(rc == 0, "error while locking scheduler mutex, pthread_mutex_lock() returned %d\n", rc); \ } while (0) #define NR_SCHED_UNLOCK(lock) \ do { \ int rc = pthread_mutex_unlock(lock); \ - AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \ + AssertFatal(rc == 0, "error while locking scheduler mutex, pthread_mutex_unlock() returned %d\n", rc); \ } while (0) #define NR_SCHED_ENSURE_LOCKED(lock)\ do {\ int rc = pthread_mutex_trylock(lock); \ - AssertFatal(rc == EBUSY, "this function should be called with the scheduler mutex locked\n");\ + AssertFatal(rc == EBUSY, "this function should be called with the scheduler mutex locked, pthread_mutex_trylock() returned %d\n", rc);\ } while (0) /* Commmon */ From aa62ddfabd4f78cbb8742b73cef29e623cd3cc37 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 8 Aug 2023 12:23:11 +0200 Subject: [PATCH 05/47] MAC: Fix check for spCellConfig before using --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e0c5879e9c..165251e9f4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2083,7 +2083,7 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s // Pause scheduling according to: // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs - const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; + const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup && UE->CellGroup->spCellConfig ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ? NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS; From 3f6ed8d14a9ef74281034181adbdd6ebe1e3ac3d Mon Sep 17 00:00:00 2001 From: Sagar Parsawar Date: Fri, 4 Nov 2022 14:59:55 +0100 Subject: [PATCH 06/47] Fix for multiple gNB SSB decode in UE phy-test mode --- executables/nr-softmodem-common.h | 2 + executables/nr-ue.c | 6 ++- executables/nr-uesoftmodem.c | 4 +- executables/nr-uesoftmodem.h | 6 ++- .../nr_dl_channel_estimation.c | 38 ++++++++++++++----- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 5 ++- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 3 +- openair2/RRC/NR_UE/main_ue.c | 4 +- openair2/RRC/NR_UE/rrc_UE.c | 14 ++++--- openair2/RRC/NR_UE/rrc_proto.h | 4 +- 11 files changed, 61 insertions(+), 27 deletions(-) diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index fe56f14ee4..8a25395abe 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -88,6 +88,8 @@ #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_DISABLETIMECORR "disable UE timing correction\n" #define CONFIG_HLP_RRC_CFG_PATH "path for RRC configuration\n" +#define CONFIG_HLP_RE_CFG_FILE "filename for reconfig.raw in phy-test mode\n" +#define CONFIG_HLP_RB_CFG_FILE "filename for rbconfig.raw in phy-test mode\n" #define CONFIG_HLP_UECAP_FILE "path for UE Capabilities file\n" #define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 8b1f6b969f..f0f9927f3c 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -946,13 +946,15 @@ void *UE_thread(void *arg) void init_NR_UE(int nb_inst, char* uecap_file, - char* rrc_config_path) { + char* rrc_config_path, + char* reconfig_file, + char* rbconfig_file) { int inst; NR_UE_MAC_INST_t *mac_inst; NR_UE_RRC_INST_t* rrc_inst; for (inst=0; inst < nb_inst; inst++) { - AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file,rrc_config_path)) != NULL, "can not initialize RRC module\n"); + AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file,rrc_config_path, reconfig_file, rbconfig_file)) != NULL, "can not initialize RRC module\n"); AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n"); AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n"); } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 1c147047c1..92f957ab8f 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -123,6 +123,8 @@ char *usrp_args = NULL; char *tx_subdev = NULL; char *rx_subdev = NULL; char *rrc_config_path = NULL; +char *reconfig_file = NULL; +char *rbconfig_file = NULL; char *uecap_file = NULL; int dumpframe = 0; @@ -472,7 +474,7 @@ int main( int argc, char **argv ) { #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - init_NR_UE(1,uecap_file,rrc_config_path); + init_NR_UE(1,uecap_file,rrc_config_path,reconfig_file,rbconfig_file); int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1; uint16_t node_number = get_softmodem_params()->node_number; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 418373ccb4..a9e18098d8 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -36,11 +36,13 @@ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&single_thread_flag, .defintval=1, TYPE_INT, 0}, \ {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \ {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, .uptr=&nrUE_params.ofdm_offset_divisor, .defuintval=8, TYPE_UINT32, 0}, \ - {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \ + {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, .iptr=(int32_t *)&nr_dlsch_demod_shift, .defintval=0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, .iptr=&vcdflag, .defintval=0, TYPE_INT, 0}, \ {"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \ {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval="./", TYPE_STRING, 0}, \ + {"reconfig_file", CONFIG_HLP_RE_CFG_FILE, 0, .strptr=&reconfig_file, .defstrval="reconfig.raw", TYPE_STRING, 0}, \ + {"rbconfig_file", CONFIG_HLP_RB_CFG_FILE, 0, .strptr=&rbconfig_file, .defstrval="rbconfig.raw", TYPE_STRING, 0}, \ {"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \ {"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&(rx_gain[0][0]), .defdblval=110, TYPE_DOUBLE, 0}, \ {"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \ @@ -91,7 +93,7 @@ extern nrUE_params_t *get_nrUE_params(void); // In nr-ue.c extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); extern void fill_ue_band_info(void); -extern void init_NR_UE(int, char*, char*); +extern void init_NR_UE(int, char*, char*, char*, char*); extern void init_NR_UE_threads(int); extern void reset_opp_meas(void); extern void print_opp_meas(void); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 60d2368a48..6684fdf222 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -34,6 +34,7 @@ #include "filt16a_32.h" #include "T.h" #include +extern openair0_config_t openair0_cfg[]; //#define DEBUG_PDSCH //#define DEBUG_PDCCH @@ -45,7 +46,7 @@ #define NO_INTERP 1 /* Generic function to find the peak of channel estimation buffer */ -void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val) +void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val) { int32_t max_val = 0, max_idx = 0, abs_val = 0; for(int k = 0; k < buf_len; k++) @@ -57,18 +58,29 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t max_idx = k; } } - *peak_val = max_val; - *peak_idx = max_idx; + + // Check for detection threshold + LOG_D(PHY,"PRS ToA estimator: max_val %d, mean_val %d, max_idx %d\n", max_val, mean_val, max_idx); + if((mean_val !=0) && (max_val/mean_val > 10)) + { + *peak_val = max_val; + *peak_idx = max_idx; + } + else + { + *peak_val = 0; + *peak_idx = 0; + } } -int nr_prs_channel_estimation(uint8_t rsc_id, +int nr_prs_channel_estimation(uint8_t gNB_id, + uint8_t rsc_id, uint8_t rep_num, PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, NR_DL_FRAME_PARMS *frame_params, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - int gNB_id = proc->gNB_id; uint8_t rxAnt = 0, idx = 0; prs_config_t *prs_cfg = &ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_cfg; prs_meas_t **prs_meas = ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_meas; @@ -84,9 +96,10 @@ int nr_prs_channel_estimation(uint8_t rsc_id, int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1]; const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr; - int16_t ch[2] = {0}, noiseFig[2] = {0}; + int16_t ch[2] = {0}; int16_t k_prime = 0, k = 0, re_offset = 0, first_half = 0, second_half = 0; - int32_t ch_pwr = 0, snr = 0; + int32_t ch_pwr = 0, snr = 0, noiseFig[2] = {0}, mean_val = 0; + double ch_pwr_dbm = 0.0f; #ifdef DEBUG_PRS_CHEST char filename[64] = {0}, varname[64] = {0}; #endif @@ -527,10 +540,17 @@ int nr_prs_channel_estimation(uint8_t rsc_id, (int16_t *)&chT_interpol[rxAnt][0],1); // peak estimator + mean_val = abs32((int32_t)ch_tmp[(prs_cfg->NumRB*12)]); peak_estimator(&chT_interpol[rxAnt][start_offset], frame_params->ofdm_symbol_size, &prs_meas[rxAnt]->dl_toa, - &ch_pwr); + &ch_pwr, + mean_val); + + // adjusting the rx_gains for channel peak power + ch_pwr_dbm = 10*log10(ch_pwr)+30 + - 10*log10(pow(2,30)) - ((int)openair0_cfg[0].rx_gain[0] + - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(frame_params->ofdm_symbol_size); //prs measurements prs_meas[rxAnt]->gNB_id = gNB_id; @@ -538,7 +558,7 @@ int nr_prs_channel_estimation(uint8_t rsc_id, prs_meas[rxAnt]->slot = proc->nr_slot_rx; prs_meas[rxAnt]->rxAnt_idx = rxAnt; prs_meas[rxAnt]->dl_aoa = rsc_id; - LOG_I(PHY, "[gNB %d][rsc %d][Rx %d][sfn %d][slot %d] DL PRS ToA ==> %d / %d samples, peak channel power %.1f dBm, SNR %+2d dB\n", gNB_id, rsc_id, rxAnt, proc->frame_rx, proc->nr_slot_rx, prs_meas[rxAnt]->dl_toa, frame_params->ofdm_symbol_size, 10*log10(ch_pwr/frame_params->ofdm_symbol_size)-30, prs_meas[rxAnt]->snr); + LOG_I(PHY, "[gNB %d][rsc %d][Rx %d][sfn %d][slot %d] DL PRS ToA ==> %d / %d samples, peak channel power %.1f dBm, SNR %+2d dB\n", gNB_id, rsc_id, rxAnt, proc->frame_rx, proc->nr_slot_rx, prs_meas[rxAnt]->dl_toa, frame_params->ofdm_symbol_size, ch_pwr_dbm, prs_meas[rxAnt]->snr); #ifdef DEBUG_PRS_CHEST sprintf(filename, "%s%i%s", "PRSpilot_", rxAnt, ".m"); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 19bc2f410c..8ac877a29e 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -33,7 +33,8 @@ #define SYNCH_HYST 2 /* A function to perform the channel estimation of DL PRS signal */ -int nr_prs_channel_estimation(uint8_t rsc_id, +int nr_prs_channel_estimation(uint8_t gNB_id, + uint8_t rsc_id, uint8_t rep_num, PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, @@ -41,7 +42,7 @@ int nr_prs_channel_estimation(uint8_t rsc_id, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); /* Generic function to find the peak of channel estimation buffer */ -void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val); +void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val); /*! \brief This function performs channel estimation including frequency and temporal interpolation diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index a800d3b8d7..8141ece1c9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -187,7 +187,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id); + LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n",ue->Mod_id, frame_parms->ssb_index); #endif return(0); } else { diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 21b344d901..0950cbdd34 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -943,7 +943,8 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, (j%fp->symbols_per_slot), rxdataF); } - nr_prs_channel_estimation(rsc_id, + nr_prs_channel_estimation(gNB_id, + rsc_id, i, ue, proc, diff --git a/openair2/RRC/NR_UE/main_ue.c b/openair2/RRC/NR_UE/main_ue.c index 5e2bc429eb..bf7e313879 100644 --- a/openair2/RRC/NR_UE/main_ue.c +++ b/openair2/RRC/NR_UE/main_ue.c @@ -34,8 +34,8 @@ #include "rrc_proto.h" #include "common/utils/LOG/log.h" -NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* rrc_config_path){ +NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* rrc_config_path, char* reconfig_file, char* rbconfig_file){ //LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n"); - return openair_rrc_top_init_ue_nr(uecap,rrc_config_path); + return openair_rrc_top_init_ue_nr(uecap,rrc_config_path,reconfig_file,rbconfig_file); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index bf9861ecfb..9881be47dd 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -345,7 +345,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, } -NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path) +NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path, char* reconfig_file, char* rbconfig_file) { if(NB_NR_UE_INST > 0) { NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(NB_NR_UE_INST , sizeof(NR_UE_RRC_INST_t)); @@ -370,10 +370,12 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_ // read in files for RRCReconfiguration and RBconfig FILE *fd; char filename[1024]; - if (rrc_config_path) - sprintf(filename,"%s/reconfig.raw",rrc_config_path); + if (rrc_config_path && reconfig_file) + sprintf(filename,"%s/%s",rrc_config_path,reconfig_file); else sprintf(filename,"reconfig.raw"); + + LOG_I(NR_RRC, "using %s for rrc init[1/2]\n",filename); fd = fopen(filename,"r"); char buffer[1024]; AssertFatal(fd, @@ -384,10 +386,12 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_ int msg_len=fread(buffer,1,1024,fd); fclose(fd); process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); - if (rrc_config_path) - sprintf(filename,"%s/rbconfig.raw",rrc_config_path); + if (rrc_config_path && rbconfig_file) + sprintf(filename,"%s/%s",rrc_config_path,rbconfig_file); else sprintf(filename,"rbconfig.raw"); + + LOG_I(NR_RRC, "using %s for rrc init[2/2]\n",filename); fd = fopen(filename,"r"); AssertFatal(fd, "cannot read file %s: errno %d, %s\n", diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 55e025e0f1..a10b3570ae 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -56,14 +56,14 @@ extern queue_t nr_ul_tti_req_queue; // main_rrc.c // /**\brief Layer 3 initialization*/ -NR_UE_RRC_INST_t* nr_l3_init_ue(char*,char*); +NR_UE_RRC_INST_t* nr_l3_init_ue(char*,char*,char*,char*); // // UE_rrc.c // /**\brief Initial the top level RRC structure instance*/ -NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char*,char*); +NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char*,char*,char*,char*); From 970e65a4d6e3fc8dbb4691d2ebac5d4a53f83c88 Mon Sep 17 00:00:00 2001 From: Sagar Parsawar Date: Tue, 6 Dec 2022 13:03:41 +0100 Subject: [PATCH 07/47] Bug fix in size of ENB_PHY_OUTPUT_SIGNAL dump --- executables/nr-ru.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 7d2b11cf65..a429d579c2 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -778,7 +778,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { unsigned int txs; int i; T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), - T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe * 4)); + T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->get_samples_per_slot(slot,fp) * 4)); int sf_extension = 0; int siglen=fp->get_samples_per_slot(slot,fp); radio_tx_burst_flag_t flags_burst = TX_BURST_INVALID; From 386881c382a5e52710f98d1fc7791877c3a96403 Mon Sep 17 00:00:00 2001 From: Sagar Parsawar Date: Mon, 12 Dec 2022 14:16:25 +0100 Subject: [PATCH 08/47] Fixed PRS IDFT 16x oversampling buffer issue --- .../nr_dl_channel_estimation.c | 86 +++++++++++-------- openair1/PHY/defs_nr_common.h | 6 +- 2 files changed, 55 insertions(+), 37 deletions(-) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 6684fdf222..b4115f53ca 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -97,8 +97,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1]; const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr; int16_t ch[2] = {0}; - int16_t k_prime = 0, k = 0, re_offset = 0, first_half = 0, second_half = 0; - int32_t ch_pwr = 0, snr = 0, noiseFig[2] = {0}, mean_val = 0; + int16_t k_prime = 0, k = 0; + int32_t ch_pwr = 0, snr = 0, noiseFig[2] = {0}, rsrp = 0, mean_val = 0, prs_toa = 0; double ch_pwr_dbm = 0.0f; #ifdef DEBUG_PRS_CHEST char filename[64] = {0}, varname[64] = {0}; @@ -106,7 +106,10 @@ int nr_prs_channel_estimation(uint8_t gNB_id, int16_t *ch_tmp = (int16_t *)ch_tmp_buf; int16_t scale_factor = (1.0f/(float)(prs_cfg->NumPRSSymbols))*(1<<15); int16_t num_pilots = (12/prs_cfg->CombSize)*prs_cfg->NumRB; - int16_t start_offset = (NR_PRS_IDFT_OVERSAMP_FACTOR-1)*frame_params->ofdm_symbol_size>>1; + int16_t first_half = frame_params->ofdm_symbol_size - frame_params->first_carrier_offset; + int16_t second_half = (prs_cfg->NumRB*12) - first_half; + int16_t start_offset = NR_PRS_IDFT_OVERSAMP_FACTOR*frame_params->ofdm_symbol_size - first_half; + LOG_D(PHY, "start_offset %d, first_half %d, second_half %d\n", start_offset, first_half, second_half); int16_t k_prime_table[K_PRIME_TABLE_ROW_SIZE][K_PRIME_TABLE_COL_SIZE] = PRS_K_PRIME_TABLE; for(int l = prs_cfg->SymbolStart; l < prs_cfg->SymbolStart+prs_cfg->NumPRSSymbols; l++) @@ -138,10 +141,11 @@ int nr_prs_channel_estimation(uint8_t gNB_id, for (rxAnt=0; rxAnt < frame_params->nb_antennas_rx; rxAnt++) { - snr = 0; + // reset variables + snr = 0; rsrp = 0; // calculate RE offset - k = re_offset = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_params->first_carrier_offset; + k = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_params->first_carrier_offset; // Channel estimation and interpolation pil = (int16_t *)&mod_prs[0]; @@ -183,7 +187,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 8); - //SNR estimation + //SNR & RSRP estimation + rsrp += squaredMod(*((c16_t*)rxF); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig)); @@ -214,7 +219,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, 8); } - //SNR estimation + //SNR & RSRP estimation + rsrp += squaredMod(*((c16_t*)rxF); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig)); @@ -242,7 +248,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, 8); } - //SNR estimation + //SNR & RSRP estimation + rsrp += squaredMod(*((c16_t*)rxF); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -263,16 +270,14 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 8); - //SNR estimation - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); + //SNR & RSRP estimation + rsrp += squaredMod(*((c16_t*)rxF); + noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); + noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); + snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); #ifdef DEBUG_PRS_PRINTS - printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, num_pilots-1, snr/num_pilots, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, num_pilots-1, snr/num_pilots, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif - // average out the SNR computed - snr = snr/num_pilots; - prs_meas[rxAnt]->snr = snr; } else if(prs_cfg->CombSize == 4) { @@ -328,7 +333,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 16); - //SNR estimation + //SNR & RSRP estimation + rsrp += squaredMod(*((c16_t*)rxF); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -346,7 +352,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 16); - //SNR estimation + //SNR & RSRP estimation + rsrp += squaredMod(*((c16_t*)rxF); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -368,7 +375,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 16); - //SNR estimation + //SNR & RSRP estimation + rsrp += squaredMod(*((c16_t*)rxF); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -389,7 +397,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 16); - //SNR estimation + //SNR & RSRP estimation + rsrp += squaredMod(*((c16_t*)rxF); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -407,21 +416,23 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 16); - //SNR estimation + //SNR & RSRP estimation + rsrp += squaredMod(*((c16_t*)rxF); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); #ifdef DEBUG_PRS_PRINTS printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, +%d) \n", rxAnt, num_pilots-1, snr/num_pilots, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif - // average out the SNR computed - snr = snr/num_pilots; - prs_meas[rxAnt]->snr = snr; } else { AssertFatal((prs_cfg->CombSize == 2)||(prs_cfg->CombSize == 4), "[%s] DL PRS CombSize other than 2 and 4 are NOT supported currently. Exiting!!!", __FUNCTION__); } + + // average out the SNR and RSRP computed + prs_meas[rxAnt]->snr = snr/(float)num_pilots; + prs_meas[rxAnt]->rsrp = rsrp/(float)num_pilots; //reset channel pointer ch_tmp = (int16_t*)ch_tmp_buf; @@ -451,12 +462,10 @@ int nr_prs_channel_estimation(uint8_t gNB_id, #endif // Place PRS channel estimates in FFT shifted format - first_half = frame_params->ofdm_symbol_size - re_offset; - second_half = (prs_cfg->NumRB*12) - first_half; if(first_half > 0) - memcpy((int16_t *)&chF_interpol[rxAnt][start_offset+re_offset], &ch_tmp[0], first_half*sizeof(int32_t)); + memcpy((int16_t *)&chF_interpol[rxAnt][start_offset], &ch_tmp[0], first_half*sizeof(int32_t)); if(second_half > 0) - memcpy((int16_t *)&chF_interpol[rxAnt][start_offset], &ch_tmp[(first_half<<1)], second_half*sizeof(int32_t)); + memcpy((int16_t *)&chF_interpol[rxAnt][0], &ch_tmp[first_half<<1], second_half*sizeof(int32_t)); // Time domain IMPULSE response idft_size_idx_t idftsizeidx; @@ -541,9 +550,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, // peak estimator mean_val = abs32((int32_t)ch_tmp[(prs_cfg->NumRB*12)]); - peak_estimator(&chT_interpol[rxAnt][start_offset], - frame_params->ofdm_symbol_size, - &prs_meas[rxAnt]->dl_toa, + peak_estimator(&chT_interpol[rxAnt][0], + NR_PRS_IDFT_OVERSAMP_FACTOR*frame_params->ofdm_symbol_size, + &prs_toa, &ch_pwr, mean_val); @@ -551,14 +560,21 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_pwr_dbm = 10*log10(ch_pwr)+30 - 10*log10(pow(2,30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(frame_params->ofdm_symbol_size); - + + prs_meas[rxAnt]->rsrp_dBm = 10*log10(prs_meas[rxAnt]->rsrp) + 30 + - 10*log10(pow(2,30)) - ((int)openair0_cfg[0].rx_gain[0] + - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size); + //prs measurements prs_meas[rxAnt]->gNB_id = gNB_id; prs_meas[rxAnt]->sfn = proc->frame_rx; prs_meas[rxAnt]->slot = proc->nr_slot_rx; prs_meas[rxAnt]->rxAnt_idx = rxAnt; prs_meas[rxAnt]->dl_aoa = rsc_id; - LOG_I(PHY, "[gNB %d][rsc %d][Rx %d][sfn %d][slot %d] DL PRS ToA ==> %d / %d samples, peak channel power %.1f dBm, SNR %+2d dB\n", gNB_id, rsc_id, rxAnt, proc->frame_rx, proc->nr_slot_rx, prs_meas[rxAnt]->dl_toa, frame_params->ofdm_symbol_size, ch_pwr_dbm, prs_meas[rxAnt]->snr); + prs_meas[rxAnt]->dl_toa = prs_toa/(float)NR_PRS_IDFT_OVERSAMP_FACTOR; + if ((frame_params->ofdm_symbol_size - prs_meas[rxAnt]->dl_toa) < frame_params->ofdm_symbol_size/2) + prs_meas[rxAnt]->dl_toa -= (frame_params->ofdm_symbol_size); + LOG_I(PHY, "[gNB %d][rsc %d][Rx %d][sfn %d][slot %d] DL PRS ToA ==> %.1f / %d samples, peak channel power %.1f dBm, SNR %+.1f dB, rsrp %+.1f dBm\n", gNB_id, rsc_id, rxAnt, proc->frame_rx, proc->nr_slot_rx, prs_meas[rxAnt]->dl_toa, frame_params->ofdm_symbol_size, ch_pwr_dbm, prs_meas[rxAnt]->snr, prs_meas[rxAnt]->rsrp_dBm); #ifdef DEBUG_PRS_CHEST sprintf(filename, "%s%i%s", "PRSpilot_", rxAnt, ".m"); @@ -581,11 +597,11 @@ int nr_prs_channel_estimation(uint8_t gNB_id, T(T_UE_PHY_DL_CHANNEL_ESTIMATE_FREQ, T_INT(gNB_id), T_INT(rsc_id), T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx), - T_INT(rxAnt), T_BUFFER(&chF_interpol[rxAnt][start_offset], frame_params->ofdm_symbol_size*sizeof(int32_t))); + T_INT(rxAnt), T_BUFFER(&chF_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR*frame_params->ofdm_symbol_size*sizeof(int32_t))); T(T_UE_PHY_DL_CHANNEL_ESTIMATE, T_INT(gNB_id), T_INT(rsc_id), T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx), - T_INT(rxAnt), T_BUFFER(&chT_interpol[rxAnt][start_offset], frame_params->ofdm_symbol_size*sizeof(int32_t))); + T_INT(rxAnt), T_BUFFER(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR*frame_params->ofdm_symbol_size*sizeof(int32_t))); } return(0); diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 13a75aaf44..a7b22cc211 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -289,9 +289,11 @@ typedef struct { int32_t sfn; int8_t slot; int8_t rxAnt_idx; - int32_t dl_toa; + float dl_toa; int32_t dl_aoa; - int32_t snr; + float snr; + float rsrp; + float rsrp_dBm; int32_t reserved; } prs_meas_t; From 4f9aa865101c591fc7571ed0254c5b512deb2dc1 Mon Sep 17 00:00:00 2001 From: Sagar Parsawar Date: Tue, 18 Apr 2023 14:26:09 +0200 Subject: [PATCH 09/47] Compile error fix --- .../nr_dl_channel_estimation.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index b4115f53ca..7e7f473b29 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -188,7 +188,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, 8); //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF); + rsrp += squaredMod(*((c16_t*)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig)); @@ -220,7 +220,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, } //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF); + rsrp += squaredMod(*((c16_t*)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig)); @@ -249,7 +249,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, } //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF); + rsrp += squaredMod(*((c16_t*)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -271,7 +271,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, 8); //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF); + rsrp += squaredMod(*((c16_t*)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -334,7 +334,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, 16); //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF); + rsrp += squaredMod(*((c16_t*)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -353,7 +353,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, 16); //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF); + rsrp += squaredMod(*((c16_t*)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -376,7 +376,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, 16); //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF); + rsrp += squaredMod(*((c16_t*)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -398,7 +398,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, 16); //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF); + rsrp += squaredMod(*((c16_t*)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -417,7 +417,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, 16); //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF); + rsrp += squaredMod(*((c16_t*)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -549,7 +549,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, (int16_t *)&chT_interpol[rxAnt][0],1); // peak estimator - mean_val = abs32((int32_t)ch_tmp[(prs_cfg->NumRB*12)]); + mean_val = squaredMod(((c16_t*)ch_tmp)[(prs_cfg->NumRB*12)>>1]); peak_estimator(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR*frame_params->ofdm_symbol_size, &prs_toa, From f64179039ec232fb5d8a02a8fd768020b5e3907a Mon Sep 17 00:00:00 2001 From: Sagar Parsawar Date: Fri, 26 May 2023 14:13:24 +0200 Subject: [PATCH 10/47] Applied clang formatting --- executables/nr-ru.c | 9 +- executables/nr-softmodem-common.h | 4 +- executables/nr-ue.c | 9 +- executables/nr-uesoftmodem.c | 6 +- executables/nr-uesoftmodem.h | 2 +- .../nr_dl_channel_estimation.c | 160 ++++++++++-------- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 2 +- openair1/PHY/defs_nr_common.h | 8 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 8 +- openair2/RRC/NR_UE/main_ue.c | 7 +- openair2/RRC/NR_UE/rrc_UE.c | 14 +- openair2/RRC/NR_UE/rrc_proto.h | 6 +- 12 files changed, 124 insertions(+), 111 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index a429d579c2..fb3b8a2e6c 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -777,8 +777,13 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { void *txp[ru->nb_tx]; unsigned int txs; int i; - T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), - T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->get_samples_per_slot(slot,fp) * 4)); + T(T_ENB_PHY_OUTPUT_SIGNAL, + T_INT(0), + T_INT(0), + T_INT(frame), + T_INT(slot), + T_INT(0), + T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot, fp, 0)], fp->get_samples_per_slot(slot, fp) * 4)); int sf_extension = 0; int siglen=fp->get_samples_per_slot(slot,fp); radio_tx_burst_flag_t flags_burst = TX_BURST_INVALID; diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index 8a25395abe..2550001956 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -88,8 +88,8 @@ #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_DISABLETIMECORR "disable UE timing correction\n" #define CONFIG_HLP_RRC_CFG_PATH "path for RRC configuration\n" -#define CONFIG_HLP_RE_CFG_FILE "filename for reconfig.raw in phy-test mode\n" -#define CONFIG_HLP_RB_CFG_FILE "filename for rbconfig.raw in phy-test mode\n" +#define CONFIG_HLP_RE_CFG_FILE "filename for reconfig.raw in phy-test mode\n" +#define CONFIG_HLP_RB_CFG_FILE "filename for rbconfig.raw in phy-test mode\n" #define CONFIG_HLP_UECAP_FILE "path for UE Capabilities file\n" #define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" diff --git a/executables/nr-ue.c b/executables/nr-ue.c index f0f9927f3c..8eae392f96 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -944,17 +944,14 @@ void *UE_thread(void *arg) return NULL; } -void init_NR_UE(int nb_inst, - char* uecap_file, - char* rrc_config_path, - char* reconfig_file, - char* rbconfig_file) { +void init_NR_UE(int nb_inst, char *uecap_file, char *rrc_config_path, char *reconfig_file, char *rbconfig_file) +{ int inst; NR_UE_MAC_INST_t *mac_inst; NR_UE_RRC_INST_t* rrc_inst; for (inst=0; inst < nb_inst; inst++) { - AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file,rrc_config_path, reconfig_file, rbconfig_file)) != NULL, "can not initialize RRC module\n"); + AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file, rrc_config_path, reconfig_file, rbconfig_file)) != NULL, "can not initialize RRC module\n"); AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n"); AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n"); } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 92f957ab8f..e746f66e9c 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -123,8 +123,8 @@ char *usrp_args = NULL; char *tx_subdev = NULL; char *rx_subdev = NULL; char *rrc_config_path = NULL; -char *reconfig_file = NULL; -char *rbconfig_file = NULL; +char *reconfig_file = NULL; +char *rbconfig_file = NULL; char *uecap_file = NULL; int dumpframe = 0; @@ -474,7 +474,7 @@ int main( int argc, char **argv ) { #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - init_NR_UE(1,uecap_file,rrc_config_path,reconfig_file,rbconfig_file); + init_NR_UE(1, uecap_file, rrc_config_path, reconfig_file, rbconfig_file); int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1; uint16_t node_number = get_softmodem_params()->node_number; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index a9e18098d8..f104aaea93 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -93,7 +93,7 @@ extern nrUE_params_t *get_nrUE_params(void); // In nr-ue.c extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); extern void fill_ue_band_info(void); -extern void init_NR_UE(int, char*, char*, char*, char*); +extern void init_NR_UE(int, char *, char *, char *, char *); extern void init_NR_UE_threads(int); extern void reset_opp_meas(void); extern void print_opp_meas(void); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 7e7f473b29..8f2e0ed5ed 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -58,16 +58,13 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t max_idx = k; } } - + // Check for detection threshold - LOG_D(PHY,"PRS ToA estimator: max_val %d, mean_val %d, max_idx %d\n", max_val, mean_val, max_idx); - if((mean_val !=0) && (max_val/mean_val > 10)) - { + LOG_D(PHY, "PRS ToA estimator: max_val %d, mean_val %d, max_idx %d\n", max_val, mean_val, max_idx); + if ((mean_val != 0) && (max_val / mean_val > 10)) { *peak_val = max_val; *peak_idx = max_idx; - } - else - { + } else { *peak_val = 0; *peak_idx = 0; } @@ -106,9 +103,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, int16_t *ch_tmp = (int16_t *)ch_tmp_buf; int16_t scale_factor = (1.0f/(float)(prs_cfg->NumPRSSymbols))*(1<<15); int16_t num_pilots = (12/prs_cfg->CombSize)*prs_cfg->NumRB; - int16_t first_half = frame_params->ofdm_symbol_size - frame_params->first_carrier_offset; - int16_t second_half = (prs_cfg->NumRB*12) - first_half; - int16_t start_offset = NR_PRS_IDFT_OVERSAMP_FACTOR*frame_params->ofdm_symbol_size - first_half; + int16_t first_half = frame_params->ofdm_symbol_size - frame_params->first_carrier_offset; + int16_t second_half = (prs_cfg->NumRB * 12) - first_half; + int16_t start_offset = NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size - first_half; LOG_D(PHY, "start_offset %d, first_half %d, second_half %d\n", start_offset, first_half, second_half); int16_t k_prime_table[K_PRIME_TABLE_ROW_SIZE][K_PRIME_TABLE_COL_SIZE] = PRS_K_PRIME_TABLE; @@ -142,10 +139,11 @@ int nr_prs_channel_estimation(uint8_t gNB_id, for (rxAnt=0; rxAnt < frame_params->nb_antennas_rx; rxAnt++) { // reset variables - snr = 0; rsrp = 0; - + snr = 0; + rsrp = 0; + // calculate RE offset - k = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_params->first_carrier_offset; + k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12 + frame_params->first_carrier_offset; // Channel estimation and interpolation pil = (int16_t *)&mod_prs[0]; @@ -187,8 +185,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 8); - //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF)); + // SNR & RSRP estimation + rsrp += squaredMod(*((c16_t *)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig)); @@ -218,9 +216,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 8); } - - //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF)); + + // SNR & RSRP estimation + rsrp += squaredMod(*((c16_t *)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig)); @@ -247,9 +245,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 8); } - - //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF)); + + // SNR & RSRP estimation + rsrp += squaredMod(*((c16_t *)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -270,13 +268,23 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 8); - //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); + // SNR & RSRP estimation + rsrp += squaredMod(*((c16_t *)rxF)); + noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0] * pil[0] - (int32_t)ch[1] * pil[1]) >> 15); + noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1] * pil[0] + (int32_t)ch[0] * pil[1]) >> 15); + snr += 10 * log10(squaredMod(*((c16_t *)rxF)) - squaredMod(*((c16_t *)noiseFig))) - 10 * log10(squaredMod(*((c16_t *)noiseFig))); #ifdef DEBUG_PRS_PRINTS - printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, num_pilots-1, snr/num_pilots, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", + rxAnt, + num_pilots - 1, + snr / num_pilots, + rxF[0], + rxF[1], + &rxF[0], + ch[0], + ch[1], + pil[0], + pil[1]); #endif } else if(prs_cfg->CombSize == 4) @@ -332,9 +340,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch, ch_tmp, 16); - - //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF)); + + // SNR & RSRP estimation + rsrp += squaredMod(*((c16_t *)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -352,8 +360,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch_tmp, 16); - //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF)); + // SNR & RSRP estimation + rsrp += squaredMod(*((c16_t *)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -374,9 +382,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch, ch_tmp, 16); - - //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF)); + + // SNR & RSRP estimation + rsrp += squaredMod(*((c16_t *)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -396,9 +404,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch, ch_tmp, 16); - - //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF)); + + // SNR & RSRP estimation + rsrp += squaredMod(*((c16_t *)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -415,9 +423,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ch, ch_tmp, 16); - - //SNR & RSRP estimation - rsrp += squaredMod(*((c16_t*)rxF)); + + // SNR & RSRP estimation + rsrp += squaredMod(*((c16_t *)rxF)); noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); @@ -429,10 +437,10 @@ int nr_prs_channel_estimation(uint8_t gNB_id, { AssertFatal((prs_cfg->CombSize == 2)||(prs_cfg->CombSize == 4), "[%s] DL PRS CombSize other than 2 and 4 are NOT supported currently. Exiting!!!", __FUNCTION__); } - + // average out the SNR and RSRP computed - prs_meas[rxAnt]->snr = snr/(float)num_pilots; - prs_meas[rxAnt]->rsrp = rsrp/(float)num_pilots; + prs_meas[rxAnt]->snr = snr / (float)num_pilots; + prs_meas[rxAnt]->rsrp = rsrp / (float)num_pilots; //reset channel pointer ch_tmp = (int16_t*)ch_tmp_buf; @@ -463,9 +471,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, // Place PRS channel estimates in FFT shifted format if(first_half > 0) - memcpy((int16_t *)&chF_interpol[rxAnt][start_offset], &ch_tmp[0], first_half*sizeof(int32_t)); + memcpy((int16_t *)&chF_interpol[rxAnt][start_offset], &ch_tmp[0], first_half * sizeof(int32_t)); if(second_half > 0) - memcpy((int16_t *)&chF_interpol[rxAnt][0], &ch_tmp[first_half<<1], second_half*sizeof(int32_t)); + memcpy((int16_t *)&chF_interpol[rxAnt][0], &ch_tmp[first_half << 1], second_half * sizeof(int32_t)); // Time domain IMPULSE response idft_size_idx_t idftsizeidx; @@ -549,32 +557,36 @@ int nr_prs_channel_estimation(uint8_t gNB_id, (int16_t *)&chT_interpol[rxAnt][0],1); // peak estimator - mean_val = squaredMod(((c16_t*)ch_tmp)[(prs_cfg->NumRB*12)>>1]); - peak_estimator(&chT_interpol[rxAnt][0], - NR_PRS_IDFT_OVERSAMP_FACTOR*frame_params->ofdm_symbol_size, - &prs_toa, - &ch_pwr, - mean_val); + mean_val = squaredMod(((c16_t *)ch_tmp)[(prs_cfg->NumRB * 12) >> 1]); + peak_estimator(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size, &prs_toa, &ch_pwr, mean_val); // adjusting the rx_gains for channel peak power - ch_pwr_dbm = 10*log10(ch_pwr)+30 - - 10*log10(pow(2,30)) - ((int)openair0_cfg[0].rx_gain[0] - - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(frame_params->ofdm_symbol_size); - - prs_meas[rxAnt]->rsrp_dBm = 10*log10(prs_meas[rxAnt]->rsrp) + 30 - - 10*log10(pow(2,30)) - ((int)openair0_cfg[0].rx_gain[0] - - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size); - + ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - 10 * log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(frame_params->ofdm_symbol_size); + + prs_meas[rxAnt]->rsrp_dBm = + 10 * log10(prs_meas[rxAnt]->rsrp) + 30 - 10 * log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size); + //prs measurements prs_meas[rxAnt]->gNB_id = gNB_id; prs_meas[rxAnt]->sfn = proc->frame_rx; prs_meas[rxAnt]->slot = proc->nr_slot_rx; prs_meas[rxAnt]->rxAnt_idx = rxAnt; prs_meas[rxAnt]->dl_aoa = rsc_id; - prs_meas[rxAnt]->dl_toa = prs_toa/(float)NR_PRS_IDFT_OVERSAMP_FACTOR; - if ((frame_params->ofdm_symbol_size - prs_meas[rxAnt]->dl_toa) < frame_params->ofdm_symbol_size/2) - prs_meas[rxAnt]->dl_toa -= (frame_params->ofdm_symbol_size); - LOG_I(PHY, "[gNB %d][rsc %d][Rx %d][sfn %d][slot %d] DL PRS ToA ==> %.1f / %d samples, peak channel power %.1f dBm, SNR %+.1f dB, rsrp %+.1f dBm\n", gNB_id, rsc_id, rxAnt, proc->frame_rx, proc->nr_slot_rx, prs_meas[rxAnt]->dl_toa, frame_params->ofdm_symbol_size, ch_pwr_dbm, prs_meas[rxAnt]->snr, prs_meas[rxAnt]->rsrp_dBm); + prs_meas[rxAnt]->dl_toa = prs_toa / (float)NR_PRS_IDFT_OVERSAMP_FACTOR; + if ((frame_params->ofdm_symbol_size - prs_meas[rxAnt]->dl_toa) < frame_params->ofdm_symbol_size / 2) + prs_meas[rxAnt]->dl_toa -= (frame_params->ofdm_symbol_size); + LOG_I(PHY, + "[gNB %d][rsc %d][Rx %d][sfn %d][slot %d] DL PRS ToA ==> %.1f / %d samples, peak channel power %.1f dBm, SNR %+.1f dB, rsrp %+.1f dBm\n", + gNB_id, + rsc_id, + rxAnt, + proc->frame_rx, + proc->nr_slot_rx, + prs_meas[rxAnt]->dl_toa, + frame_params->ofdm_symbol_size, + ch_pwr_dbm, + prs_meas[rxAnt]->snr, + prs_meas[rxAnt]->rsrp_dBm); #ifdef DEBUG_PRS_CHEST sprintf(filename, "%s%i%s", "PRSpilot_", rxAnt, ".m"); @@ -595,13 +607,21 @@ int nr_prs_channel_estimation(uint8_t gNB_id, T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx), T_INT(rxAnt), T_BUFFER(&rxdataF[rxAnt][0], frame_params->samples_per_slot_wCP*sizeof(int32_t))); - T(T_UE_PHY_DL_CHANNEL_ESTIMATE_FREQ, T_INT(gNB_id), T_INT(rsc_id), - T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx), - T_INT(rxAnt), T_BUFFER(&chF_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR*frame_params->ofdm_symbol_size*sizeof(int32_t))); + T(T_UE_PHY_DL_CHANNEL_ESTIMATE_FREQ, + T_INT(gNB_id), + T_INT(rsc_id), + T_INT(proc->frame_rx), + T_INT(proc->nr_slot_rx), + T_INT(rxAnt), + T_BUFFER(&chF_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size * sizeof(int32_t))); - T(T_UE_PHY_DL_CHANNEL_ESTIMATE, T_INT(gNB_id), T_INT(rsc_id), - T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx), - T_INT(rxAnt), T_BUFFER(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR*frame_params->ofdm_symbol_size*sizeof(int32_t))); + T(T_UE_PHY_DL_CHANNEL_ESTIMATE, + T_INT(gNB_id), + T_INT(rsc_id), + T_INT(proc->frame_rx), + T_INT(proc->nr_slot_rx), + T_INT(rxAnt), + T_BUFFER(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size * sizeof(int32_t))); } return(0); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 8141ece1c9..a03555f772 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -187,7 +187,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n",ue->Mod_id, frame_parms->ssb_index); + LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); #endif return(0); } else { diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index a7b22cc211..0741291fb4 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -289,11 +289,11 @@ typedef struct { int32_t sfn; int8_t slot; int8_t rxAnt_idx; - float dl_toa; + float dl_toa; int32_t dl_aoa; - float snr; - float rsrp; - float rsrp_dBm; + float snr; + float rsrp; + float rsrp_dBm; int32_t reserved; } prs_meas_t; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 0950cbdd34..3c5c7e250a 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -943,13 +943,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, (j%fp->symbols_per_slot), rxdataF); } - nr_prs_channel_estimation(gNB_id, - rsc_id, - i, - ue, - proc, - fp, - rxdataF); + nr_prs_channel_estimation(gNB_id, rsc_id, i, ue, proc, fp, rxdataF); } } // for i } // for rsc_id diff --git a/openair2/RRC/NR_UE/main_ue.c b/openair2/RRC/NR_UE/main_ue.c index bf7e313879..37aff4ff9b 100644 --- a/openair2/RRC/NR_UE/main_ue.c +++ b/openair2/RRC/NR_UE/main_ue.c @@ -34,8 +34,9 @@ #include "rrc_proto.h" #include "common/utils/LOG/log.h" -NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* rrc_config_path, char* reconfig_file, char* rbconfig_file){ - //LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n"); +NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* rrc_config_path, char* reconfig_file, char* rbconfig_file) +{ + // LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n"); - return openair_rrc_top_init_ue_nr(uecap,rrc_config_path,reconfig_file,rbconfig_file); + return openair_rrc_top_init_ue_nr(uecap, rrc_config_path, reconfig_file, rbconfig_file); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 9881be47dd..e13274b14a 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -344,7 +344,6 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, } - NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path, char* reconfig_file, char* rbconfig_file) { if(NB_NR_UE_INST > 0) { @@ -371,11 +370,11 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_ FILE *fd; char filename[1024]; if (rrc_config_path && reconfig_file) - sprintf(filename,"%s/%s",rrc_config_path,reconfig_file); + sprintf(filename, "%s/%s", rrc_config_path, reconfig_file); else sprintf(filename,"reconfig.raw"); - - LOG_I(NR_RRC, "using %s for rrc init[1/2]\n",filename); + + LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", filename); fd = fopen(filename,"r"); char buffer[1024]; AssertFatal(fd, @@ -387,11 +386,11 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_ fclose(fd); process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); if (rrc_config_path && rbconfig_file) - sprintf(filename,"%s/%s",rrc_config_path,rbconfig_file); + sprintf(filename, "%s/%s", rrc_config_path, rbconfig_file); else sprintf(filename,"rbconfig.raw"); - - LOG_I(NR_RRC, "using %s for rrc init[2/2]\n",filename); + + LOG_I(NR_RRC, "using %s for rrc init[2/2]\n", filename); fd = fopen(filename,"r"); AssertFatal(fd, "cannot read file %s: errno %d, %s\n", @@ -418,7 +417,6 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_ return NR_UE_rrc_inst; } - int8_t nr_ue_process_rlc_bearer_list(NR_CellGroupConfig_t *cell_group_config){ return 0; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index a10b3570ae..94ea697c87 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -56,16 +56,14 @@ extern queue_t nr_ul_tti_req_queue; // main_rrc.c // /**\brief Layer 3 initialization*/ -NR_UE_RRC_INST_t* nr_l3_init_ue(char*,char*,char*,char*); +NR_UE_RRC_INST_t *nr_l3_init_ue(char *, char *, char *, char *); // // UE_rrc.c // /**\brief Initial the top level RRC structure instance*/ -NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char*,char*,char*,char*); - - +NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *, char *, char *, char *); /**\brief Decode RRC Connection Reconfiguration, sent from E-UTRA RRC Connection Reconfiguration v1510 carring EN-DC config \param buffer encoded NR-RRC-Connection-Reconfiguration/Secondary-Cell-Group-Config message. From 53171d96ead08f7b5c00e13cb7e34bea82afe110 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 13 Jun 2023 13:30:00 +0200 Subject: [PATCH 11/47] addressing reviewer comments: rename prs config files (remove "sa") and updating doc accordingly --- doc/RUN_NR_PRS.md | 12 ++++++------ ...conf => gnb0.prs.band261.fr2.64PRB.usrpx310.conf} | 0 ...conf => gnb0.prs.band78.fr1.106PRB.usrpx310.conf} | 0 ...conf => gnb1.prs.band261.fr2.64PRB.usrpx310.conf} | 0 ...conf => gnb1.prs.band78.fr1.106PRB.usrpx310.conf} | 0 5 files changed, 6 insertions(+), 6 deletions(-) rename targets/PROJECTS/GENERIC-NR-5GC/CONF/{gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf => gnb0.prs.band261.fr2.64PRB.usrpx310.conf} (100%) rename targets/PROJECTS/GENERIC-NR-5GC/CONF/{gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf => gnb0.prs.band78.fr1.106PRB.usrpx310.conf} (100%) rename targets/PROJECTS/GENERIC-NR-5GC/CONF/{gnb1.sa.band261.fr2.64PRB.prs.usrpx310.conf => gnb1.prs.band261.fr2.64PRB.usrpx310.conf} (100%) rename targets/PROJECTS/GENERIC-NR-5GC/CONF/{gnb1.sa.band78.fr1.106PRB.prs.usrpx310.conf => gnb1.prs.band78.fr1.106PRB.usrpx310.conf} (100%) diff --git a/doc/RUN_NR_PRS.md b/doc/RUN_NR_PRS.md index 64e754cb0f..af2f5f0325 100644 --- a/doc/RUN_NR_PRS.md +++ b/doc/RUN_NR_PRS.md @@ -21,8 +21,8 @@ After you have [built the softmodem executables](BUILD.md), go to the build dire | **Mode** | **gNB config** | **nrUE config** | |----------------------------- |------------------------------------------------------------------------------------------- |--------------------------- | -| **FR1 40MHz
30kHz SCS** | gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf
gnb1.sa.band78.fr1.106PRB.prs.usrpx310.conf | ue.nr.prs.fr1.106prb.conf | -| **FR2 100MHz
120kHz SCS** | gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf
gnb1.sa.band261.fr2.64PRB.prs.usrpx310.conf | ue.nr.prs.fr2.64prb.conf | +| **FR1 40MHz
30kHz SCS** | gnb0.prs.band78.fr1.106PRB.usrpx310.conf
gnb1.prs.band78.fr1.106PRB.usrpx310.conf | ue.nr.prs.fr1.106prb.conf | +| **FR2 100MHz
120kHz SCS** | gnb0.prs.band261.fr2.64PRB.usrpx310.conf
gnb1.prs.band261.fr2.64PRB.usrpx310.conf | ue.nr.prs.fr2.64prb.conf | Under gNB and nrUE config files, parameters are configured under `prs_config` section. nrUE is capable to receive downlink PRS signal from multiple gNB simultaneously and therefore nrUE config file contains multiple `prs_config` sections, corresponding to each gNB. These parameters can be changed as per the test scenario. @@ -64,26 +64,26 @@ In our case the output is 0 and hence we use `numactl --cpunodebind=0 --membind= ## FR1 test Open a terminal on the host machine, and execute below command to launch gNB with **X310 USRPs** -```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf --phy-test``` +```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf --phy-test``` If **N310 USRPs** are used, then run above command `without -E option` i.e without 3/4 sampling rate.

To run using **rfsimulator**, execute following command: -```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test``` +```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test``` ## FR2 test In FR2 mode, we need RF beamforming module to transmit signal in mmWave frequency range. **X310 USRPs** can be used with BasicTx daughtercard to transmit baseband signal at **Intermediate Frequncy(IF)** and then RF beamforming module would perform beamforming and the upconversion to FR2 frequencies. IF can be specified using `if_freq` in the RU section of gNB config. If RF beamforming module is NOT present, gNB can still be launched with USRP alone; to transmit at supported `if_freq`. -```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf --phy-test```

+```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf --phy-test```

To run using **rfsimulator**, execute following command: -```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test``` +```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test``` ## Multiple gNB scenario PRS is primarily used for positioning and localization of the UE with multiple gNBs transmitting simultaneously. OAI PRS implementation supports multiple gNB transmission provided all the gNBs are tightely synchronized using GPSDO clock. Therefore before running this scenario, make sure the USRPs has built-in GPSDO and the GPS antennas are connected with good satellite visibility. Also every time a gNB is launched, wait until `GPS LOCKED` is printed on the terminal during gNB startup. If USRP fails to lock with GPSDO, try again until its locked. diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf similarity index 100% rename from targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf rename to targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf similarity index 100% rename from targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf rename to targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.sa.band261.fr2.64PRB.prs.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band261.fr2.64PRB.usrpx310.conf similarity index 100% rename from targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.sa.band261.fr2.64PRB.prs.usrpx310.conf rename to targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band261.fr2.64PRB.usrpx310.conf diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.sa.band78.fr1.106PRB.prs.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf similarity index 100% rename from targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.sa.band78.fr1.106PRB.prs.usrpx310.conf rename to targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf From 9983478a616e0ca8edaed6b1c13a465ca44c1e3a Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 13 Jun 2023 13:30:45 +0200 Subject: [PATCH 12/47] addressing reviewer comments: removing warning messages --- openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 8f2e0ed5ed..0de7dbaa9c 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -93,9 +93,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1]; const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr; - int16_t ch[2] = {0}; + int16_t ch[2] = {0}, noiseFig[2] = {0}; int16_t k_prime = 0, k = 0; - int32_t ch_pwr = 0, snr = 0, noiseFig[2] = {0}, rsrp = 0, mean_val = 0, prs_toa = 0; + int32_t ch_pwr = 0, snr = 0, rsrp = 0, mean_val = 0, prs_toa = 0; double ch_pwr_dbm = 0.0f; #ifdef DEBUG_PRS_CHEST char filename[64] = {0}, varname[64] = {0}; From 9f45f1d76917c0bdb55d7c35044a955de311bac0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 9 Aug 2023 17:32:40 +0200 Subject: [PATCH 13/47] Deprecate NR-UE --rrc_config_path, use --r{e,b}config-file instead Config options --reconfig_file and --rbconfig-file have been introduced to modify the filenames of reconfig.raw and rbconfig.raw (e.g., in the case of multiple UEs). These filen*ames* were to be prepended with --rrc_config_path to set the path. In summary, three options were necessary, when two are sufficient. In this commit, change to the options --reconfig-file and --rbconfig-file (slight change for harmonization with other options, which mostly use dashes) to give the full path to the corresponding files, and avoid to surprise users who would not expect to have three options. --rrc_config_path has been deprecated and an error will be printed if a user attempts to use it. --- ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml | 2 +- .../gnb_nr_ue_usrp_run_multi_thread.xml | 2 +- .../docker-compose.yaml | 2 +- .../docker-compose.yaml | 2 +- .../docker-compose.yaml | 2 +- doc/RUN_NR_NFAPI.md | 4 +-- executables/nr-ue.c | 4 +-- executables/nr-uesoftmodem.c | 4 ++- executables/nr-uesoftmodem.h | 8 +++--- openair2/RRC/NR_UE/main_ue.c | 4 +-- openair2/RRC/NR_UE/rrc_UE.c | 26 ++++++------------- openair2/RRC/NR_UE/rrc_proto.h | 4 +-- radio/rfsimulator/README.md | 2 +- 13 files changed, 29 insertions(+), 37 deletions(-) diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml index 1c4faaf99f..b07bd2b6dd 100644 --- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml @@ -52,7 +52,7 @@ Initialize_OAI_UE Initialize NR UE USRP - --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 50 --rrc_config_path . --log_config.global_log_options level,nocolor,time + --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 50 --log_config.global_log_options level,nocolor,time NR diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml index 2122f8651c..dfc088fc34 100644 --- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml +++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml @@ -52,7 +52,7 @@ Initialize_OAI_UE Initialize NR UE USRP - --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --rrc_config_path . --log_config.global_log_options level,nocolor,time + --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --log_config.global_log_options level,nocolor,time NR diff --git a/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml index a23c823019..5ead5b485e 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml @@ -23,7 +23,7 @@ services: privileged: true container_name: rfsim5g-oai-nr-ue environment: - USE_ADDITIONAL_OPTIONS: --phy-test --rfsim --noS1 --rrc_config_path etc/rrc/ --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: --phy-test --rfsim --noS1 --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time volumes: - ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf - rrc.config:/opt/oai-nr-ue/etc/rrc/ diff --git a/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml index 4875f88eb9..10d57983b8 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml @@ -23,7 +23,7 @@ services: privileged: true container_name: rfsim5g-oai-nr-ue environment: - USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --rrc_config_path etc/rrc/ --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time volumes: - ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf - rrc.config:/opt/oai-nr-ue/etc/rrc/ diff --git a/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml index da3f8eaf31..dc1998dffa 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml @@ -23,7 +23,7 @@ services: privileged: true container_name: rfsim5g-oai-nr-ue environment: - USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --rrc_config_path etc/rrc/ --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time volumes: - ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf - rrc.config:/opt/oai-nr-ue/etc/rrc/ diff --git a/doc/RUN_NR_NFAPI.md b/doc/RUN_NR_NFAPI.md index 503fead0ed..5b597aa326 100644 --- a/doc/RUN_NR_NFAPI.md +++ b/doc/RUN_NR_NFAPI.md @@ -31,7 +31,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfap ``` ### UE command ``` -sudo ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . -d --rfsimulator.serveraddr 127.0.0.1 +sudo ./nr-uesoftmodem --rfsim --phy-test -d --rfsimulator.serveraddr 127.0.0.1 ``` ## Procedure to run NR nFAPI using Hardware (tested with USRP x310) @@ -48,7 +48,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfap ``` ### UE command ``` -sudo ./nr-uesoftmodem --usrp-args "addr=*USRP_ADDRESS*,clock_source=external,time_source=external" --phy-test --rrc_config_path ../../../ci-scripts/rrc-files +sudo ./nr-uesoftmodem --usrp-args "addr=*USRP_ADDRESS*,clock_source=external,time_source=external" --phy-test ``` diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 8eae392f96..1c6bca50b4 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -944,14 +944,14 @@ void *UE_thread(void *arg) return NULL; } -void init_NR_UE(int nb_inst, char *uecap_file, char *rrc_config_path, char *reconfig_file, char *rbconfig_file) +void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file) { int inst; NR_UE_MAC_INST_t *mac_inst; NR_UE_RRC_INST_t* rrc_inst; for (inst=0; inst < nb_inst; inst++) { - AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file, rrc_config_path, reconfig_file, rbconfig_file)) != NULL, "can not initialize RRC module\n"); + AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file, reconfig_file, rbconfig_file)) != NULL, "can not initialize RRC module\n"); AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n"); AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n"); } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index e746f66e9c..35a9f9a473 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -264,6 +264,8 @@ static void get_options(void) { int numparams = sizeof(cmdline_params)/sizeof(paramdef_t); config_get(cmdline_params,numparams,NULL); + AssertFatal(rrc_config_path == NULL, "the option \"rrc_config_path\" is deprecated. Please use --reconfig-file and --rbconfig-file separately to point to files reconfig.raw and rbconfig.raw\n"); + if (vcdflag > 0) ouput_vcd = 1; } @@ -474,7 +476,7 @@ int main( int argc, char **argv ) { #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - init_NR_UE(1, uecap_file, rrc_config_path, reconfig_file, rbconfig_file); + init_NR_UE(1, uecap_file, reconfig_file, rbconfig_file); int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1; uint16_t node_number = get_softmodem_params()->node_number; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index f104aaea93..3549a7fae1 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -40,9 +40,9 @@ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, .iptr=(int32_t *)&nr_dlsch_demod_shift, .defintval=0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, .iptr=&vcdflag, .defintval=0, TYPE_INT, 0}, \ {"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \ - {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval="./", TYPE_STRING, 0}, \ - {"reconfig_file", CONFIG_HLP_RE_CFG_FILE, 0, .strptr=&reconfig_file, .defstrval="reconfig.raw", TYPE_STRING, 0}, \ - {"rbconfig_file", CONFIG_HLP_RB_CFG_FILE, 0, .strptr=&rbconfig_file, .defstrval="rbconfig.raw", TYPE_STRING, 0}, \ + {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval=NULL, TYPE_STRING, 0}, \ + {"reconfig-file", CONFIG_HLP_RE_CFG_FILE, 0, .strptr=&reconfig_file, .defstrval="./reconfig.raw", TYPE_STRING, 0}, \ + {"rbconfig-file", CONFIG_HLP_RB_CFG_FILE, 0, .strptr=&rbconfig_file, .defstrval="./rbconfig.raw", TYPE_STRING, 0}, \ {"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \ {"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&(rx_gain[0][0]), .defdblval=110, TYPE_DOUBLE, 0}, \ {"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \ @@ -93,7 +93,7 @@ extern nrUE_params_t *get_nrUE_params(void); // In nr-ue.c extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); extern void fill_ue_band_info(void); -extern void init_NR_UE(int, char *, char *, char *, char *); +extern void init_NR_UE(int, char *, char *, char *); extern void init_NR_UE_threads(int); extern void reset_opp_meas(void); extern void print_opp_meas(void); diff --git a/openair2/RRC/NR_UE/main_ue.c b/openair2/RRC/NR_UE/main_ue.c index 37aff4ff9b..72853cd278 100644 --- a/openair2/RRC/NR_UE/main_ue.c +++ b/openair2/RRC/NR_UE/main_ue.c @@ -34,9 +34,9 @@ #include "rrc_proto.h" #include "common/utils/LOG/log.h" -NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* rrc_config_path, char* reconfig_file, char* rbconfig_file) +NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* reconfig_file, char* rbconfig_file) { // LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n"); - return openair_rrc_top_init_ue_nr(uecap, rrc_config_path, reconfig_file, rbconfig_file); + return openair_rrc_top_init_ue_nr(uecap, reconfig_file, rbconfig_file); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index e13274b14a..01a0178b62 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -344,7 +344,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, } -NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path, char* reconfig_file, char* rbconfig_file) +NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_file, char* rbconfig_file) { if(NB_NR_UE_INST > 0) { NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(NB_NR_UE_INST , sizeof(NR_UE_RRC_INST_t)); @@ -367,34 +367,24 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_ if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) { // read in files for RRCReconfiguration and RBconfig - FILE *fd; - char filename[1024]; - if (rrc_config_path && reconfig_file) - sprintf(filename, "%s/%s", rrc_config_path, reconfig_file); - else - sprintf(filename,"reconfig.raw"); - LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", filename); - fd = fopen(filename,"r"); - char buffer[1024]; + LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", reconfig_file); + FILE *fd = fopen(reconfig_file,"r"); AssertFatal(fd, "cannot read file %s: errno %d, %s\n", - filename, + reconfig_file, errno, strerror(errno)); + char buffer[1024]; int msg_len=fread(buffer,1,1024,fd); fclose(fd); process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); - if (rrc_config_path && rbconfig_file) - sprintf(filename, "%s/%s", rrc_config_path, rbconfig_file); - else - sprintf(filename,"rbconfig.raw"); - LOG_I(NR_RRC, "using %s for rrc init[2/2]\n", filename); - fd = fopen(filename,"r"); + LOG_I(NR_RRC, "using %s for rrc init[2/2]\n", rbconfig_file); + fd = fopen(rbconfig_file,"r"); AssertFatal(fd, "cannot read file %s: errno %d, %s\n", - filename, + rbconfig_file, errno, strerror(errno)); msg_len=fread(buffer,1,1024,fd); diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 94ea697c87..df2d44a996 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -56,14 +56,14 @@ extern queue_t nr_ul_tti_req_queue; // main_rrc.c // /**\brief Layer 3 initialization*/ -NR_UE_RRC_INST_t *nr_l3_init_ue(char *, char *, char *, char *); +NR_UE_RRC_INST_t *nr_l3_init_ue(char *, char *, char *); // // UE_rrc.c // /**\brief Initial the top level RRC structure instance*/ -NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *, char *, char *, char *); +NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *, char *, char *); /**\brief Decode RRC Connection Reconfiguration, sent from E-UTRA RRC Connection Reconfiguration v1510 carring EN-DC config \param buffer encoded NR-RRC-Connection-Reconfiguration/Secondary-Cell-Group-Config message. diff --git a/radio/rfsimulator/README.md b/radio/rfsimulator/README.md index e8baff472c..ca05343c4f 100644 --- a/radio/rfsimulator/README.md +++ b/radio/rfsimulator/README.md @@ -119,7 +119,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78 ### Launch UE in another window ```bash -sudo ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . --rfsimulator.serveraddr +sudo ./nr-uesoftmodem --rfsim --phy-test --rfsimulator.serveraddr ``` Notes: From a87cd3e83c567cbb0e595187592a73d469ee9c6a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 9 Aug 2023 17:38:05 +0200 Subject: [PATCH 14/47] Rewrite RUNMODEM.md section for phytest; simplify rfsim doc --- doc/RUNMODEM.md | 25 ++++++++++++++----------- radio/rfsimulator/README.md | 14 +++----------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 28df446291..f7321c4ad1 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -127,27 +127,30 @@ Some other useful paramters of the UE are ## phy-test setup with OAI UE -The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC. In this case both gNB and eNB need to be run with the --phy-test flag. At the gNB this flag does the following +The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC and circumventing random access. In this case both gNB and eNB need to be run with the `--phy-test` flag. At the gNB this flag does the following - it reads the RRC configuration from the configuration file - - it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw - - the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload - -At the UE the --phy-test flag will - - read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them. + - it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files `rbconfig.raw` and `reconfig.raw` in the current directory + - the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload instead of the standard scheduler. The options `-m`, `-l`, `-t`, `-M`, `-T`, `-D`, and `-U` can be used to configure this scheduler. See `./nr-softmodem -h` for more information. +At the UE, the `--phy-test` flag will read the binary files `rbconfig.raw` and `reconfig.raw` from the current directory and process them. If you wish to provide a different path for these files, please use the options `--reconfig-file` and `--rbconfig-file`. ```bash sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test ``` -In phy-test mode it is possible to mimic the reception of UE Capabilities at gNB by passing through the command line parameter `--uecap_file` the location and file name of the input UE Capability file, e.g. `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports1.xml` (1 layer) or `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports2.xml` (2 layers). - ```bash -sudo ./nr-uesoftmodem --phy-test [--rrc_config_path ../../../ci-scripts/rrc-files] +sudo ./nr-uesoftmodem --phy-test [--reconfig-file ../../../ci-scripts/rrc-files/reconfig.raw --rbconfig-file ../../../ci-scripts/rrc-files/rbconfig.raw] ``` -You need to provide `--rrc_config_path` if you don't start the UE after the gNB -in the same directory. +In summary: +- If you are running on the same machine and launched the 2 executables (`nr-softmodem` and `nr-uesoftmodem`) from the same directory, nothing has to be done. +- If you launched the 2 executables from 2 different folders, just point to the location where you launched the `nr-softmodem`: + * `sudo ./nr-uesoftmodem --rfsim --phy-test --reconfig-file /the/path/where/you/launched/nr-softmodem/reconfig-file --rbconfig-file /the/path/where/you/launched/nr-softmodem/rbconfig-file --rfsimulator.serveraddr ` +- If you are not running on the same machine, you need to **COPY** the two raw files + * `scp usera@machineA:/the/path/where/you/launched/nr-softmodem/r*config.raw userb@machineB:/the/path/where/you/will/launch/nr-uesoftmodem/` + * Obviously this operation should be done before launching the `nr-uesoftmodem` executable. + +In phy-test mode it is possible to mimic the reception of UE Capabilities at gNB by passing through the command line parameter `--uecap_file` the location and file name of the input UE Capability file, e.g. `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports1.xml` (1 layer) or `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports2.xml` (2 layers). ## noS1 setup with OAI UE diff --git a/radio/rfsimulator/README.md b/radio/rfsimulator/README.md index ca05343c4f..1974e55f50 100644 --- a/radio/rfsimulator/README.md +++ b/radio/rfsimulator/README.md @@ -124,18 +124,10 @@ sudo ./nr-uesoftmodem --rfsim --phy-test --rfsimulator.serveraddr can be 127.0.0.1 if both gNB and nrUE executables run on the same host, OR the IP interface address of the remote host running the gNB executable, if the gNB and nrUE run on separate hosts. -3. The --rrc_config_path parameter SHALL specify where the 2 RAW files are located (`rbconfig.raw` and `reconfig.raw`). - - If you are running on the same machine and launched the 2 executables (`nr-softmodem` and `nr-uesoftmodem`) from the same directory, nothing has to be done. - - If you launched the 2 executables from 2 different folders, just point to the location where you launched the `nr-softmodem`: - * `sudo ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path /the/path/where/you/launched/nr-softmodem --rfsimulator.serveraddr ` - - If you are not running on the same machine or launched the 2 executables from 2 different folders, you need to **COPY** the 2 raw files - * `scp usera@machineA:/the/path/where/you/launched/nr-softmodem/r*config.raw userb@machineB:/the/path/where/you/will/launch/nr-uesoftmodem/` - * Obviously this operation SHALL be done before launching the `nr-uesoftmodem` executable. -4. To enable the noS1 mode, `--noS1` option should be added to the command line. -5. To operate the gNB/UE with a 5GC, start them using the `--sa` option. More information can be found [here](../../../doc/NR_SA_Tutorial_OAI_CN5G.md). - +3. To enable the noS1 mode, `--noS1` option should be added to the command line, see again [RUNMODEM.md](../../doc/RUNMODEM.md). +4. To operate the gNB/UE with a 5GC, start them using the `--sa` option. More information can be found [here](../../../doc/NR_SA_Tutorial_OAI_CN5G.md). In the UE, you can add `-d` option to get the softscope. From 26ef1128d89057dbf1e334c1b7233ca9214ef6f3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 9 Aug 2023 17:40:48 +0200 Subject: [PATCH 15/47] Initialize OAIgraph before usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Newer GCC releases warn about the scope being uninitialized: openair1/PHY/TOOLS/nr_phy_scope.c:1076:20: error: ‘graph.text’ is used uninitialized [-Werror=uninitialized] This is correct, as we don't initialize the scope. This commit correctly initializes the scope. --- openair1/PHY/TOOLS/nr_phy_scope.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index d07bf07076..79ac95ef73 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -193,7 +193,9 @@ void websrv_setpoint(int x, int y, websrv_scopedata_msg_t *msg) msg->data_xy[msg->data_xy[0]] = (int16_t)y; } #endif -static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) { +static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) +{ + memset(graph, 0, sizeof(*graph)); if (type==WATERFALL) { graph->waterFallh=h-15; graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh); From 66df72d1f83bbc42a37f45a926958275cac1fae8 Mon Sep 17 00:00:00 2001 From: Imad Al Samman Date: Tue, 8 Aug 2023 11:38:56 +0200 Subject: [PATCH 16/47] USRP driver: Make it compile for UHD < 4.0.0 --- radio/USRP/usrp_lib.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index 06b0c9bace..03058869e8 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -269,11 +269,6 @@ static void trx_usrp_start_interdigital_gpio(openair0_device *device, usrp_state { AssertFatal(device->type == USRP_X400_DEV, "interdigital frontend device for beam management can only be used together with an X400\n"); - - // s->gpio_bank="GPIO0"; - std::vector sxx{12, "DB0_RF0"}; - // set every pin on GPIO0 to be ocntrolled by DB1_RF0 - s->usrp->set_gpio_src(s->gpio_bank, sxx); // set data direction register (DDR) to output s->usrp->set_gpio_attr(s->gpio_bank, "DDR", 0xfff, 0xfff); // set lower GPIO#1 to be controlled automatically by ATR (the rest bits are controlled manually) From f3c2c12fa2f42d5e401da954db06364f55671e28 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 8 Aug 2023 16:06:56 +0200 Subject: [PATCH 17/47] Fix alignment of Tpool user data to 32 bytes The thread pool provides user data to be stored by (pre-)allocating the necessary memory. A previous attempt was made to have this user data aligned on a 32 byte boundary (e.g., to prevent segfault with SIMD instructions, or avoid inefficient data access); the current implementation, however, leads to unaligned memory access. This patch attempts again to implement user data to be 32 byte aligned. First, use memalign() to allocate the actual job on a 32 byte boundary. Second, use alignas(32) to align the pointer to the user data to be aligned to 32 bytes. Since it is the last member of the struct, this ensures that user data, which is allocated right behind it, will be aligned to 32 bytes as well. --- common/utils/threadPool/thread-pool.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index 66e1152f48..1a78e20134 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -26,6 +26,8 @@ #define THREAD_POOL_H #include #include +#include +#include #include #include #include @@ -64,7 +66,10 @@ typedef struct notifiedFIFO_elt_s { oai_cputime_t startProcessingTime; oai_cputime_t endProcessingTime; oai_cputime_t returnTime; - void *msgData; + // use alignas(32) to align msgData to 32b + // user data behind it will be aligned to 32b as well + // important! this needs to be the last member in the struct + alignas(32) void *msgData; } notifiedFIFO_elt_t; typedef struct notifiedFIFO_s { @@ -80,14 +85,15 @@ static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size, uint64_t key, notifiedFIFO_t *reponseFifo, void (*processingFunc)(void *)) { - notifiedFIFO_elt_t *ret; - AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) calloc(1, sizeof(notifiedFIFO_elt_t)+size+32)), ""); + notifiedFIFO_elt_t *ret = (notifiedFIFO_elt_t *)memalign(32, sizeof(notifiedFIFO_elt_t) + size); + AssertFatal(NULL != ret, "out of memory\n"); ret->next=NULL; ret->key=key; ret->reponseFifo=reponseFifo; ret->processingFunc=processingFunc; // We set user data piece aligend 32 bytes to be able to process it with SIMD - ret->msgData=(void *)((uint8_t*)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32); + // msgData is aligned to 32bytes, so everything after will be as well + ret->msgData = ((uint8_t *)ret) + sizeof(notifiedFIFO_elt_t); ret->malloced=true; return ret; } From ab9f9bdd76cd0caf5e1a7ccac135ededee1decf4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 26 Jul 2023 17:03:08 +0200 Subject: [PATCH 18/47] Don't delete RA in delete_nr_ue_data() for reusing the old UE Context after reestablishment: we have to free a UE context, but that also free's the RA process that we still need. Remove here Is this necessary? --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 68a44fa0cf..3922f57185 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1992,22 +1992,7 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca destroy_nr_list(&sched_ctrl->retrans_ul_harq); uid_linear_allocator_free(uia, UE->uid); LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti); - const rnti_t rnti = UE->rnti; free(UE); - - /* clear RA process(es?) associated to the UE */ - for (int cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) { - for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - NR_COMMON_channels_t *cc = &ccPtr[cc_id]; - if (cc->ra[i].rnti == rnti) { - LOG_D(NR_MAC, "free RA process %d for rnti %04x\n", i, rnti); - /* is it enough? */ - cc->ra[i].cfra = false; - cc->ra[i].rnti = 0; - cc->ra[i].crnti = 0; - } - } - } } From 50bba6b2875f493d000d61918fff8ab3ceaa3deb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 4 Jul 2023 16:58:11 +0200 Subject: [PATCH 19/47] Remove useless S1AP definitions in NR RRC --- openair2/RRC/NR/nr_rrc_defs.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 51ef9d0f8d..40d0e10762 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -283,11 +283,6 @@ typedef struct gNB_RRC_UE_s { /* Information from UE RRCReestablishmentRequest */ NR_ReestablishmentCause_t reestablishment_cause; - /* UE id for initial connection to S1AP */ - uint16_t ue_initial_id; - - /* Information from S1AP initial_context_setup_req */ - uint32_t gNB_ue_s1ap_id :24; uint32_t gNB_ue_ngap_id; uint64_t amf_ue_ngap_id; nr_rrc_guami_t ue_guami; From d647a98f65a907ce9b26435301e5ecb0f2bf187f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 30 May 2023 15:06:07 +0200 Subject: [PATCH 20/47] Make the gNB_ue_ngap_id greater than 0 To avoid 0 in the ID --- openair2/RRC/NR/rrc_gNB_UE_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 2d2742aa4a..fc9c40c4ae 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -66,7 +66,7 @@ rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance LOG_E(NR_RRC, "Cannot allocate new ue context\n"); return NULL; } - new_p->ue_context.gNB_ue_ngap_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator); + new_p->ue_context.gNB_ue_ngap_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator) + 1; for(int i = 0; i < NB_RB_MAX; i++) new_p->ue_context.pduSession[i].xid = -1; @@ -120,7 +120,7 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST *rrc_instance_pP, rrc_gNB_ue_context } RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); - uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.gNB_ue_ngap_id); + uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.gNB_ue_ngap_id - 1); rrc_gNB_free_mem_ue_context(ue_context_pP); LOG_I(NR_RRC, "Removed UE context\n"); } From f1cef982f2bd9bc05d7cd61a96e174215e71ec64 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 31 May 2023 06:59:58 +0200 Subject: [PATCH 21/47] Bugfix: DL RRC Message: Allocate RRC Container buf --- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 5bfeda2dc8..21c8ff9500 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -76,6 +76,12 @@ static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); f1ap_ue_context_release_cmd_t *msg = &F1AP_UE_CONTEXT_RELEASE_CMD(message_p); *msg = *cmd; + if (cmd->rrc_container_length > 0) { + msg->rrc_container = calloc(cmd->rrc_container_length, sizeof(*msg->rrc_container)); + AssertFatal(msg->rrc_container != NULL, "out of memory\n"); + msg->rrc_container_length = cmd->rrc_container_length; + memcpy(msg->rrc_container, cmd->rrc_container, cmd->rrc_container_length); + } itti_send_msg_to_task (TASK_CU_F1, 0, message_p); } From 97b65555fdaa3defceda7f23691b4605e5bc7b35 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 4 Jul 2023 15:22:25 +0200 Subject: [PATCH 22/47] Invalid free: do not free RRC container --- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 582420a0b4..6959be3677 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -266,9 +266,6 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) .rnti = cmd->rnti, }; mac->mac_rrc.ue_context_release_complete(&complete); - - if (cmd->rrc_container) - free(cmd->rrc_container); } int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) From c5b99629543f2fbac9bea697e029e0b2928feb86 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 26 May 2023 12:15:05 +0200 Subject: [PATCH 23/47] Remove unnecessary dl_rrc_message_transfer_direct() --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 2 +- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 4 ++-- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h | 2 +- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 2 +- openair2/RRC/NR/mac_rrc_dl.h | 2 +- openair2/RRC/NR/mac_rrc_dl_direct.c | 9 +-------- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 4 ++-- openair2/RRC/NR/rrc_gNB.c | 6 +++--- 8 files changed, 12 insertions(+), 19 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 5fc8daef3f..c701efe36c 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -140,7 +140,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, .rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id), .srb_id = srb_id }; - dl_rrc_message(instance, &dl_rrc); + dl_rrc_message_transfer(&dl_rrc); return 0; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 6959be3677..108c909c06 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -268,10 +268,10 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) mac->mac_rrc.ue_context_release_complete(&complete); } -int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) { LOG_D(NR_MAC, "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", dl_rrc->rrc_container_length, dl_rrc->rnti, dl_rrc->srb_id); + /* the DU ue id is the RNTI */ nr_rlc_srb_recv_sdu(dl_rrc->rnti, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length); - return 0; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 808277a7f4..859e128b4a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -29,6 +29,6 @@ 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); void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd); -int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); +void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc); #endif /* MAC_RRC_DL_HANDLER_H */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 7a798d7b81..f7fa3f1f78 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -750,7 +750,7 @@ void deliver_pdu_srb_f1(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, .rrc_container_length = size, .rnti = ue_id, .srb_id = srb_id}; - rrc->mac_rrc.dl_rrc_message_transfer(0, &dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); } static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 2728174603..94920f6f64 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -29,7 +29,7 @@ typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *r typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req); typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); -typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); +typedef void (*dl_rrc_message_transfer_func_t)(const f1ap_dl_rrc_message_t *dl_rrc); struct nr_mac_rrc_dl_if_s; void mac_rrc_dl_direct_init(struct nr_mac_rrc_dl_if_s *mac_rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index 2d436c19e3..eeec72e132 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -24,17 +24,10 @@ #include "mac_rrc_dl.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" -static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) -{ - /* TODO how to manage inter-thread communication? */ - - dl_rrc_message(module_id, dl_rrc); -} - void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request; mac_rrc->ue_context_modification_request = ue_context_modification_request; mac_rrc->ue_context_release_command = ue_context_release_command; - mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; + mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 21c8ff9500..0aa9dbac35 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -85,7 +85,7 @@ static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t itti_send_msg_to_task (TASK_CU_F1, 0, message_p); } -static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +static void dl_rrc_message_transfer_f1ap(const f1ap_dl_rrc_message_t *dl_rrc) { /* TODO call F1AP function directly? no real-time constraint here */ @@ -98,7 +98,7 @@ static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rr msg->rrc_container_length = dl_rrc->rrc_container_length; memcpy(msg->rrc_container, dl_rrc->rrc_container, dl_rrc->rrc_container_length); } - itti_send_msg_to_task (TASK_CU_F1, module_id, message_p); + itti_send_msg_to_task (TASK_CU_F1, 0, message_p); } void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index f731ed0fbe..47ae15042c 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -476,7 +476,7 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, .rnti = ue_p->rnti, .srb_id = CCCH }; - rrc->mac_rrc.dl_rrc_message_transfer(instance, &dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); } //----------------------------------------------------------------------------- @@ -532,7 +532,7 @@ static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t m .rnti = ue_p->rnti, .srb_id = CCCH }; - rrc_instance_p->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc); + rrc_instance_p->mac_rrc.dl_rrc_message_transfer(&dl_rrc); return xid; } @@ -565,7 +565,7 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context .execute_duplication = 1, .RAT_frequency_priority_information.en_dc = 0 }; - rrc->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); } //----------------------------------------------------------------------------- From 4574a19fc90d35891a2985a081634ef234d2c07a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 25 Jul 2023 15:55:55 +0200 Subject: [PATCH 24/47] Rename primary RRC UE ID gNB_ue_ngap_id to rrc_ue_id The RRC uses gNB_ue_ngap_id as its primary ID; the following commits will introduce the usage of the (F1) gNB CU UE ID. This commits renames the gNB_ue_ngap_id to rrc_ue_id to better reflect its usage as the RRC's primary UE ID. It will be used as the NGAP and F1 (CU) UE IDs. --- openair2/F1AP/f1ap_cu_ue_context_management.c | 2 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 2 +- openair2/RRC/NR/nr_rrc_defs.h | 2 +- openair2/RRC/NR/rrc_gNB.c | 6 ++--- openair2/RRC/NR/rrc_gNB_NGAP.c | 22 +++++++++---------- openair2/RRC/NR/rrc_gNB_UE_context.c | 18 +++++++-------- openair2/RRC/NR/rrc_gNB_nsa.c | 7 +++--- 7 files changed, 29 insertions(+), 30 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 8fdee52abb..cd5eb0ae95 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -966,7 +966,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, if (ue_context_p) { MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE); - NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id; + NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.rrc_ue_id; itti_send_msg_to_task(TASK_NGAP, instance, msg); rrc_gNB_remove_ue_context(RC.nrrrc[instance], ue_context_p); } else { diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 75446708a9..65e15ce115 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -783,7 +783,7 @@ int16_t do_RRCReconfiguration( } if(cellGroupConfig!=NULL){ - update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.gNB_ue_ngap_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration); + update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.rrc_ue_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 40d0e10762..36d9ae1b53 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -283,7 +283,7 @@ typedef struct gNB_RRC_UE_s { /* Information from UE RRCReestablishmentRequest */ NR_ReestablishmentCause_t reestablishment_cause; - uint32_t gNB_ue_ngap_id; + uint32_t rrc_ue_id; uint64_t amf_ue_ngap_id; nr_rrc_guami_t ue_guami; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 47ae15042c..1c48c0781e 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1321,7 +1321,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx /* Update RNTI in ue_context */ LOG_I(NR_RRC, "RRC Reestablishment - Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); - rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->gNB_ue_ngap_id); + rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->rrc_ue_id); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); @@ -2295,7 +2295,7 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) nr_pdcp_remove_UE(UE->rnti); newGtpuDeleteAllTunnels(instance, UE->rnti); - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->gNB_ue_ngap_id); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->rrc_ue_id); LOG_I(NR_RRC, "removed UE %04x \n", UE->rnti); rrc_gNB_remove_ue_context(rrc, ue_context_p); } @@ -2311,7 +2311,7 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i if (resp->drbs_to_be_setup_length > 0) { e1ap_bearer_setup_req_t req = {0}; req.numPDUSessionsMod = UE->nb_of_pdusessions; - req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id; + req.gNB_cu_cp_ue_id = UE->rrc_ue_id; req.rnti = UE->rnti; for (int i = 0; i < req.numPDUSessionsMod; i++) { req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index f0a7f3b90f..517c1f31c2 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -182,7 +182,7 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ( ngap_nas_first_req_t *req = &NGAP_NAS_FIRST_REQ(message_p); memset(req, 0, sizeof(*req)); - req->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + req->gNB_ue_ngap_id = UE->rrc_ue_id; /* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */ AssertFatal(UE->establishment_cause < NGAP_RRC_CAUSE_LAST, "Establishment cause invalid (%jd/%d) for gNB %d!", UE->establishment_cause, NGAP_RRC_CAUSE_LAST, ctxt_pP->module_id); @@ -436,7 +436,7 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c ngap_initial_context_setup_resp_t *resp = &NGAP_INITIAL_CONTEXT_SETUP_RESP(msg_p); gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; - resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + resp->gNB_ue_ngap_id = UE->rrc_ue_id; for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) { rrc_pdu_session_param_t *session = &UE->pduSession[pdusession]; @@ -641,7 +641,7 @@ rrc_gNB_send_NGAP_UPLINK_NAS( pdu_length = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->size; pdu_buffer = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->buf; msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UPLINK_NAS); - NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id; NGAP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; // extract_imsi(NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer, @@ -668,7 +668,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP); ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_p); gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; - resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + resp->gNB_ue_ngap_id = UE->rrc_ue_id; for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) { rrc_pdu_session_param_t *session = &UE->pduSession[pdusession]; @@ -745,7 +745,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins return ; } - UE->gNB_ue_ngap_id = msg->gNB_ue_ngap_id; + UE->rrc_ue_id = msg->gNB_ue_ngap_id; UE->amf_ue_ngap_id = msg->amf_ue_ngap_id; e1ap_bearer_setup_req_t bearer_req = {0}; @@ -1009,7 +1009,7 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP( ngap_pdusession_modify_resp_t *resp = &NGAP_PDUSESSION_MODIFY_RESP(msg_p); LOG_I(NR_RRC, "send message NGAP_PDUSESSION_MODIFY_RESP \n"); - resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + resp->gNB_ue_ngap_id = UE->rrc_ue_id; for (int i = 0; i < UE->nb_of_pdusessions; i++) { if (xid != UE->pduSession[i].xid) { @@ -1087,7 +1087,7 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, con MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_REQ); ngap_ue_release_req_t *req = &NGAP_UE_CONTEXT_RELEASE_REQ(msg); memset(req, 0, sizeof(*req)); - req->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + req->gNB_ue_ngap_id = UE->rrc_ue_id; req->cause = causeP; req->cause_value = cause_valueP; for (int i = 0; i < UE->nb_of_pdusessions; i++) { @@ -1202,7 +1202,7 @@ void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP, msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UE_CAPABILITIES_IND); ngap_ue_cap_info_ind_t *ind = &NGAP_UE_CAPABILITIES_IND(msg_p); memset(ind, 0, sizeof(*ind)); - ind->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + ind->gNB_ue_ngap_id = UE->rrc_ue_id; ind->ue_radio_cap.length = encoded; ind->ue_radio_cap.buffer = buf2; itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); @@ -1224,7 +1224,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_RELEASE_RESPONSE); ngap_pdusession_release_resp_t *resp = &NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p); memset(resp, 0, sizeof(*resp)); - resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + resp->gNB_ue_ngap_id = UE->rrc_ue_id; for (int i = 0; i < UE->nb_of_pdusessions; i++) { if (xid == UE->pduSession[i].xid) { @@ -1239,7 +1239,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( resp->nb_of_pdusessions_released = pdu_sessions_released; resp->nb_of_pdusessions_failed = 0; - LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released); + LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: rrc_ue_id %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); } @@ -1266,7 +1266,7 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ gNB_RRC_UE_t *UE = &ue_context_p->ue_context; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); LOG_I( - NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease); + NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu rrc_ue_id %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease); bool found = false; uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id); UE->xids[xid] = RRC_PDUSESSION_RELEASE; diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index fc9c40c4ae..94123830d7 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -41,11 +41,11 @@ int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t *c1_pP, rrc_gNB_ue_context_t *c2_pP) //------------------------------------------------------------------------------ { - if (c1_pP->ue_context.gNB_ue_ngap_id > c2_pP->ue_context.gNB_ue_ngap_id) { + if (c1_pP->ue_context.rrc_ue_id > c2_pP->ue_context.rrc_ue_id) { return 1; } - if (c1_pP->ue_context.gNB_ue_ngap_id < c2_pP->ue_context.gNB_ue_ngap_id) { + if (c1_pP->ue_context.rrc_ue_id < c2_pP->ue_context.rrc_ue_id) { return -1; } @@ -66,12 +66,12 @@ rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance LOG_E(NR_RRC, "Cannot allocate new ue context\n"); return NULL; } - new_p->ue_context.gNB_ue_ngap_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator) + 1; + new_p->ue_context.rrc_ue_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator) + 1; for(int i = 0; i < NB_RB_MAX; i++) new_p->ue_context.pduSession[i].xid = -1; - LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.gNB_ue_ngap_id); + LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.rrc_ue_id); return(new_p); } @@ -82,7 +82,7 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context(gNB_RRC_INST *rrc_instance_pP, ue_i { rrc_gNB_ue_context_t temp; /* gNB ue rrc id = 24 bits wide */ - temp.ue_context.gNB_ue_ngap_id = ue; + temp.ue_context.rrc_ue_id = ue; return RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp); } @@ -120,7 +120,7 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST *rrc_instance_pP, rrc_gNB_ue_context } RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); - uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.gNB_ue_ngap_id - 1); + uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.rrc_ue_id - 1); rrc_gNB_free_mem_ue_context(ue_context_pP); LOG_I(NR_RRC, "Removed UE context\n"); } @@ -153,11 +153,11 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_insta return NULL; } -void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, uint32_t gNB_ue_ngap_id) +void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, uint32_t rrc_ue_id) { // rnti will need to be a fast access key, with indexing, today it is sequential search // This function will update the index when it will be made - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, gNB_ue_ngap_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, rrc_ue_id); if (ue_context_p) ue_context_p->ue_context.rnti = rnti; else @@ -182,6 +182,6 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST *rrc_i ue_context_p->ue_context.rnti = rnti; ue_context_p->ue_context.random_ue_identity = ue_identityP; RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p); - LOG_W(NR_RRC, " Created new UE context rnti: %04x, random ue id %lx, RRC ue id %u\n", rnti, ue_identityP, ue_context_p->ue_context.gNB_ue_ngap_id); + LOG_W(NR_RRC, " Created new UE context rnti: %04x, random ue id %lx, RRC ue id %u\n", rnti, ue_identityP, ue_context_p->ue_context.rrc_ue_id); return ue_context_p; } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 656c7d0663..ddfc1fae38 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -248,14 +248,13 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a 1, 1, configuration, - ue_context_p->ue_context.gNB_ue_ngap_id); + ue_context_p->ue_context.rrc_ue_id); AssertFatal(UE->secondaryCellGroup != NULL, "out of memory\n"); xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->secondaryCellGroup); - fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.gNB_ue_ngap_id); + fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.rrc_ue_id); // the UE context is not yet inserted in the RRC UE manager - // rrc_gNB_update_ue_context_rnti(UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, rrc, - // UE->gNB_ue_ngap_id); + // rrc_gNB_update_ue_context_rnti(UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, rrc, UE->rrc_ue_id); UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void *)CG_Config,0,sizeof(*CG_Config)); From af545c07b75ff407b81cfb4a26b5af654516223c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 5 Jun 2023 20:15:35 +0200 Subject: [PATCH 25/47] Hashtable for F1 UE IDs and add test --- CMakeLists.txt | 3 +- openair2/F1AP/CMakeLists.txt | 7 ++ openair2/F1AP/f1ap_ids.c | 157 ++++++++++++++++++++++++++++++++++ openair2/F1AP/f1ap_ids.h | 48 +++++++++++ openair2/F1AP/f1ap_ids_test.c | 42 +++++++++ 5 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 openair2/F1AP/f1ap_ids.c create mode 100644 openair2/F1AP/f1ap_ids.h create mode 100644 openair2/F1AP/f1ap_ids_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d06d30c17..948f623f2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -413,6 +413,7 @@ target_link_libraries(x2ap PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) set(F1AP_DIR ${OPENAIR2_DIR}/F1AP) add_library(f1ap ${F1AP_DIR}/f1ap_common.c + ${F1AP_DIR}/f1ap_ids.c ${F1AP_DIR}/f1ap_cu_interface_management.c ${F1AP_DIR}/f1ap_cu_paging.c ${F1AP_DIR}/f1ap_cu_rrc_message_transfer.c @@ -431,7 +432,7 @@ add_library(f1ap ${F1AP_DIR}/f1ap_itti_messaging.c) target_include_directories(f1ap PUBLIC F1AP_DIR) target_link_libraries(f1ap PUBLIC asn1_f1ap) -target_link_libraries(f1ap PRIVATE ngap nr_rrc) +target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE) # LPP ############## diff --git a/openair2/F1AP/CMakeLists.txt b/openair2/F1AP/CMakeLists.txt index 7537bd661d..e6490b96b0 100644 --- a/openair2/F1AP/CMakeLists.txt +++ b/openair2/F1AP/CMakeLists.txt @@ -1 +1,8 @@ add_subdirectory(MESSAGES) + +if(ENABLE_TESTS) + add_executable(f1ap_ids_test f1ap_ids_test.c f1ap_ids.c) + target_link_libraries(f1ap_ids_test UTIL HASHTABLE minimal_lib) + add_dependencies(tests f1ap_ids_test) + add_test(NAME F1AP_ID_test COMMAND f1ap_ids_test) +endif() diff --git a/openair2/F1AP/f1ap_ids.c b/openair2/F1AP/f1ap_ids.c new file mode 100644 index 0000000000..e467e074fd --- /dev/null +++ b/openair2/F1AP/f1ap_ids.c @@ -0,0 +1,157 @@ +/* + * 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 + */ + +/* "standalone" module to store a "secondary" UE ID for each UE in DU/CU. + * Separate from the rest of F1, as it is also relevant for monolithic. */ + +#include "f1ap_ids.h" + +#include +#include "common/utils/hashtable/hashtable.h" +#include "common/utils/assertions.h" + + +/* we have separate versions for CU and DU, as both CU&DU might coexist in the + * same process */ +static hash_table_t *cu2du_ue_mapping; +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() + DevAssert(cu2du_ue_mapping != NULL); + pthread_mutex_unlock(&cu2du_mutex); +} + +bool cu_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data) +{ + pthread_mutex_lock(&cu2du_mutex); + DevAssert(cu2du_ue_mapping != NULL); + uint64_t key = ue_id; + if (hashtable_is_key_exists(cu2du_ue_mapping, key) == HASH_TABLE_OK) { + pthread_mutex_unlock(&cu2du_mutex); + return false; + } + f1_ue_data_t *idata = malloc(sizeof(*idata)); + AssertFatal(idata != NULL, "cannot allocate memory\n"); + *idata = *data; + hashtable_rc_t ret = hashtable_insert(cu2du_ue_mapping, key, idata); + pthread_mutex_unlock(&cu2du_mutex); + return ret == HASH_TABLE_OK; +} + +bool cu_exists_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&cu2du_mutex); + DevAssert(cu2du_ue_mapping != NULL); + uint64_t key = ue_id; + hashtable_rc_t ret = hashtable_is_key_exists(cu2du_ue_mapping, key); + pthread_mutex_unlock(&cu2du_mutex); + return ret == HASH_TABLE_OK; +} + +f1_ue_data_t cu_get_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&cu2du_mutex); + DevAssert(cu2du_ue_mapping != NULL); + uint64_t key = ue_id; + void *data = NULL; + hashtable_rc_t ret = hashtable_get(cu2du_ue_mapping, key, &data); + AssertFatal(ret == HASH_TABLE_OK && data != NULL, "element for ue_id %d not found\n", ue_id); + f1_ue_data_t ued = *(f1_ue_data_t *)data; + pthread_mutex_unlock(&cu2du_mutex); + return ued; +} + +bool cu_remove_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&cu2du_mutex); + DevAssert(cu2du_ue_mapping != NULL); + uint64_t key = ue_id; + hashtable_rc_t ret = hashtable_remove(cu2du_ue_mapping, key); + pthread_mutex_unlock(&cu2du_mutex); + return ret == HASH_TABLE_OK; +} + +/* DU version below */ +static hash_table_t *du2cu_ue_mapping; +static pthread_mutex_t du2cu_mutex = PTHREAD_MUTEX_INITIALIZER; + +void du_init_f1_ue_data(void) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping == NULL); + du2cu_ue_mapping = hashtable_create(1319, NULL, free); // 1319 is prime, default hash func (unit), free() + DevAssert(du2cu_ue_mapping != NULL); + pthread_mutex_unlock(&du2cu_mutex); +} + +bool du_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping != NULL); + uint64_t key = ue_id; + if (hashtable_is_key_exists(du2cu_ue_mapping, key) == HASH_TABLE_OK) { + pthread_mutex_unlock(&du2cu_mutex); + return false; + } + f1_ue_data_t *idata = malloc(sizeof(*idata)); + AssertFatal(idata != NULL, "cannot allocate memory\n"); + *idata = *data; + hashtable_rc_t ret = hashtable_insert(du2cu_ue_mapping, key, idata); + pthread_mutex_unlock(&du2cu_mutex); + return ret == HASH_TABLE_OK; +} + +bool du_exists_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping != NULL); + uint64_t key = ue_id; + hashtable_rc_t ret = hashtable_is_key_exists(du2cu_ue_mapping, key); + pthread_mutex_unlock(&du2cu_mutex); + return ret == HASH_TABLE_OK; +} + +f1_ue_data_t du_get_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping != NULL); + uint64_t key = ue_id; + void *data = NULL; + hashtable_rc_t ret = hashtable_get(du2cu_ue_mapping, key, &data); + AssertFatal(ret == HASH_TABLE_OK && data != NULL, "element for ue_id %d not found\n", ue_id); + f1_ue_data_t ued = *(f1_ue_data_t *)data; + pthread_mutex_unlock(&du2cu_mutex); + return ued; +} + +bool du_remove_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping != NULL); + uint64_t key = ue_id; + hashtable_rc_t ret = hashtable_remove(du2cu_ue_mapping, key); + pthread_mutex_unlock(&du2cu_mutex); + return ret == HASH_TABLE_OK; +} diff --git a/openair2/F1AP/f1ap_ids.h b/openair2/F1AP/f1ap_ids.h new file mode 100644 index 0000000000..96b146f6ba --- /dev/null +++ b/openair2/F1AP/f1ap_ids.h @@ -0,0 +1,48 @@ +/* + * 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 + */ + +/* "standalone" module to store a "secondary" UE ID for each UE in DU/CU. + * Separate from the rest of F1, as it is also relevant for monolithic. */ + +#ifndef F1AP_IDS_H_ +#define F1AP_IDS_H_ + +#include +#include + +typedef struct f1_ue_data_t { + uint32_t secondary_ue; + /* can be extended with F1-specific data also relevant for monolithic */ +} f1_ue_data_t; + +void cu_init_f1_ue_data(void); +bool cu_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data); +bool cu_exists_f1_ue_data(uint32_t ue_id); +f1_ue_data_t cu_get_f1_ue_data(uint32_t ue_id); +bool cu_remove_f1_ue_data(uint32_t ue_id); + +void du_init_f1_ue_data(void); +bool du_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data); +bool du_exists_f1_ue_data(uint32_t ue_id); +f1_ue_data_t du_get_f1_ue_data(uint32_t ue_id); +bool du_remove_f1_ue_data(uint32_t ue_id); + +#endif /* F1AP_IDS_H_ */ diff --git a/openair2/F1AP/f1ap_ids_test.c b/openair2/F1AP/f1ap_ids_test.c new file mode 100644 index 0000000000..3007db566a --- /dev/null +++ b/openair2/F1AP/f1ap_ids_test.c @@ -0,0 +1,42 @@ +/* + * 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 +#include +#include +#include "common/utils/assertions.h" +#include "f1ap_ids.h" + +int main() +{ + du_init_f1_ue_data(); + int rnti = 13; + f1_ue_data_t data = {.secondary_ue = 1}; + bool ret = du_add_f1_ue_data(rnti, &data); + DevAssert(ret); + ret = du_add_f1_ue_data(rnti, &data); + DevAssert(!ret); + bool exists = du_exists_f1_ue_data(rnti); + DevAssert(exists); + f1_ue_data_t rdata = du_get_f1_ue_data(rnti); + DevAssert(rdata.secondary_ue == data.secondary_ue); + return 0; +} From 3e0f07705c2df8f8e6fec8a1e63860f89001c6a7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 3 Jul 2023 18:36:12 +0200 Subject: [PATCH 26/47] Init F1 UE data structs at MAC, RRC & CU-UP --- executables/nr-cuup.c | 2 ++ openair2/LAYER2/NR_MAC_gNB/main.c | 3 +++ openair2/RRC/NR/rrc_gNB.c | 2 ++ 3 files changed, 7 insertions(+) diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index ffa50a766b..81d255b87d 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -27,6 +27,7 @@ #include "common/ran_context.h" #include "nfapi/oai_integration/vendor_ext.h" #include "openair2/F1AP/f1ap_common.h" +#include "openair2/F1AP/f1ap_ids.h" #include "openair2/GNB_APP/gnb_config.h" #include "nr_pdcp/nr_pdcp_oai_api.h" @@ -134,6 +135,7 @@ int main(int argc, char **argv) rc = itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL); AssertFatal(rc >= 0, "Create task for CUUP E1 failed\n"); nr_pdcp_layer_init(); + cu_init_f1_ue_data(); // for CU-UP/CP mapping: we use the same MessageDef *msg = RCconfig_NR_CU_E1(true); AssertFatal(msg != NULL, "Send init to task for E1AP UP failed\n"); itti_send_msg_to_task(TASK_CUUP_E1, 0, msg); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index cdba0b676b..ed16ffd1d7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -40,6 +40,7 @@ #include "nr_rlc/nr_rlc_oai_api.h" #include "RRC/NR/MESSAGES/asn1_msg.h" //#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "openair2/F1AP/f1ap_ids.h" #include "common/ran_context.h" #include "executables/softmodem-common.h" @@ -301,5 +302,7 @@ void mac_top_init_gNB(ngran_node_t node_type) memset(&nrmac->UE_info, 0, sizeof(nrmac->UE_info)); } + du_init_f1_ue_data(); + srand48(0); } diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 1c48c0781e..5a865f88e1 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -97,6 +97,7 @@ #include #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" #include "openair2/F1AP/f1ap_common.h" +#include "openair2/F1AP/f1ap_ids.h" #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" #include "cucp_cuup_if.h" @@ -310,6 +311,7 @@ static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc) AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type); break; } + cu_init_f1_ue_data(); } static void openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration) From 0a0f6b7952b537b6ed4464c06f8629cd1b4b5126 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 26 May 2023 14:20:39 +0200 Subject: [PATCH 27/47] Initial UL RRC Message: manage DU UE ID at CU --- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 57 ++++++------------- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 25 +++----- openair2/F1AP/f1ap_du_rrc_message_transfer.h | 9 +-- openair2/F1AP/f1ap_du_task.c | 2 +- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 1 + openair2/RRC/NR/nr_rrc_defs.h | 1 + openair2/RRC/NR/rrc_gNB.c | 38 +++++++++---- openair2/RRC/NR/rrc_gNB_UE_context.c | 26 +++++++-- openair2/RRC/NR/rrc_gNB_UE_context.h | 5 +- 9 files changed, 82 insertions(+), 82 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 5c3b100efd..09c9633780 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -53,9 +53,6 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, MessageDef *message_p; F1AP_InitialULRRCMessageTransfer_t *container; F1AP_InitialULRRCMessageTransferIEs_t *ie; - rnti_t rnti; - sdu_size_t ccch_sdu_len; - int CC_id =0; DevAssert(pdu != NULL); if (stream != 0) { @@ -68,6 +65,8 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + uint32_t du_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + /* NRCGI * Fixme: process NRCGI */ @@ -78,7 +77,7 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, /* RNTI */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_C_RNTI, true); - rnti = ie->value.choice.C_RNTI; + rnti_t rnti = ie->value.choice.C_RNTI; F1AP_InitialULRRCMessageTransferIEs_t *rrccont; F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, rrccont, container, F1AP_ProtocolIE_ID_id_RRCContainer, true); @@ -96,43 +95,21 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, } // create an ITTI message and copy SDU - if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) { - message_p = itti_alloc_new_message (TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); - f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p); - ul_rrc->nr_cellid = nr_cellid; // CU instance - ul_rrc->crnti = rnti; - ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size; - ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length); - memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length); - AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n"); - ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size; - ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); - memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length); - itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); - } else { - message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND); - memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - ccch_sdu_len = rrccont->value.choice.RRCContainer.size; - memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, rrccont->value.choice.RRCContainer.buf, - ccch_sdu_len); - NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0; - NR_RRC_MAC_CCCH_DATA_IND (message_p).slot = 0; - NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len; - NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance - NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; - NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; - if (du2cu) { - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t)); - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = du2cu->value.choice.DUtoCURRCContainer.size; - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(du2cu->value.choice.DUtoCURRCContainer.size); - memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf, - du2cu->value.choice.DUtoCURRCContainer.buf, - du2cu->value.choice.DUtoCURRCContainer.size); - } - itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p); - } + AssertFatal(f1ap_req(true, instance)->cell_type == CELL_MACRO_GNB, "illegal cell type %d\n", f1ap_req(true, instance)->cell_type); + message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p); + ul_rrc->gNB_DU_ue_id = du_ue_id; + ul_rrc->nr_cellid = nr_cellid; // CU instance + ul_rrc->crnti = rnti; + ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size; + ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length); + memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length); + AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n"); + ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size; + ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); + memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length); + itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); - //getCxt(true,ITTI_MSG_DESTINATION_ID(message_p))->f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id; return 0; } diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index c701efe36c..c694c3a227 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -145,19 +145,13 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } /* UL RRC Message Transfer */ -int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, - int CC_idP, - int UE_id, - rnti_t rntiP, - const uint8_t *sduP, - sdu_size_t sdu_lenP, - const uint8_t *sdu2P, - sdu_size_t sdu2_lenP) { +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_InitialULRRCMessageTransfer_t *out; uint8_t *buffer=NULL; uint32_t len=0; - int f1ap_uid = f1ap_add_ue (DUtype, instanceP, rntiP); + int f1ap_uid = f1ap_add_ue(DUtype, instanceP, msg->crnti); if (f1ap_uid < 0 ) { LOG_E(F1AP, "Failed to add UE \n"); @@ -178,7 +172,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, ie1->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie1->value.choice.GNB_DU_UE_F1AP_ID = getCxt(DUtype, instanceP)->f1ap_ue[f1ap_uid].du_ue_f1ap_id; + ie1->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; /* mandatory */ /* c2. NRCGI */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie2); @@ -193,25 +187,25 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, ie3->id = F1AP_ProtocolIE_ID_id_C_RNTI; ie3->criticality = F1AP_Criticality_reject; ie3->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI; - ie3->value.choice.C_RNTI=rntiP; + ie3->value.choice.C_RNTI = msg->crnti; /* mandatory */ /* c4. RRCContainer */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie4); ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; ie4->criticality = F1AP_Criticality_reject; ie4->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)sduP, sdu_lenP); + OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length); /* optional */ /* c5. DUtoCURRCContainer */ - if (sdu2P) { + if (msg->du2cu_rrc_container != NULL) { asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie5); ie5->id = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer; ie5->criticality = F1AP_Criticality_reject; ie5->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer; OCTET_STRING_fromBuf(&ie5->value.choice.DUtoCURRCContainer, - (const char *)sdu2P, - sdu2_lenP); + (const char *)msg->du2cu_rrc_container, + msg->du2cu_rrc_container_length); } /* mandatory */ /* c6. Transaction ID (integer value) */ @@ -231,7 +225,6 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, return 0; } - int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) { const rnti_t rnti = msg->rnti; diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h index 7a0c1f8974..f784b7a0cf 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.h +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h @@ -43,13 +43,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg); -int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, - int CC_idP, - int UE_id, - rnti_t rntiP, - const uint8_t *sduP, - sdu_size_t sdu_lenP, - const uint8_t *sdu2P, - sdu_size_t sdu2_lenP); +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg); #endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */ diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 098f957194..a7af049c2a 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -145,7 +145,7 @@ void *F1AP_DU_task(void *arg) { case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc { f1ap_initial_ul_rrc_message_t *msgRrc = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); - DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0, 0, 0, msgRrc->crnti, msgRrc->rrc_container, msgRrc->rrc_container_length, msgRrc->du2cu_rrc_container, msgRrc->du2cu_rrc_container_length); + DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(myInstance, msgRrc); } break; case F1AP_UL_RRC_MESSAGE: // to rrc diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 3922f57185..3f68575c15 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2907,6 +2907,7 @@ void send_initial_ul_rrc_message(gNB_MAC_INST *mac, int rnti, const uint8_t *sdu const f1ap_initial_ul_rrc_message_t ul_rrc_msg = { /* TODO: add mcc, mnc, cell_id, ..., is not available at MAC yet */ + .gNB_DU_ue_id = rnti, .crnti = rnti, .rrc_container = (uint8_t *) sdu, .rrc_container_length = sdu_len, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 36d9ae1b53..560d7a2a9c 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -271,6 +271,7 @@ typedef struct gNB_RRC_UE_s { e_NR_IntegrityProtAlgorithm integrity_algorithm; NR_UE_STATE_t StatusRrc; + uint32_t cu_ue_id; rnti_t rnti; uint64_t random_ue_identity; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 5a865f88e1..9b069b5b66 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -489,7 +489,11 @@ static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t m rrc_gNB_ue_context_t *ue_context_pP = NULL; gNB_RRC_INST *rrc_instance_p = RC.nrrrc[module_id]; - ue_context_pP = rrc_gNB_create_ue_context(rnti, rrc_instance_p, 0); + AssertFatal(!NODE_IS_CU(rrc_instance_p->node_type), "Not functional in F1-split: no DU UE ID available\n"); + /* for creating a UE context, we need the DU ID to be able to indicate the + * DU. This is not yet implemented for Reestablishment. We know that in + * monolithic, the DU UE ID is the RNTI, so use that for the moment */ + ue_context_pP = rrc_gNB_create_ue_context(rnti, rrc_instance_p, 0, rnti); gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; unsigned char buf[1024]; @@ -1468,7 +1472,7 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP } /*------------------------------------------------------------------------------*/ -static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint8_t *buffer, int buffer_length, const uint8_t *du_to_cu_rrc_container, int du_to_cu_rrc_container_len) +static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *msg) { module_id_t Idx; asn_dec_rval_t dec_rval; @@ -1476,9 +1480,11 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[module_id]; NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; + rnti_t rnti = msg->crnti; - LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", rnti, buffer_length); - dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **) &ul_ccch_msg, buffer, buffer_length, 0, 0); + LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", rnti, msg->rrc_container_length); + dec_rval = + uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **)&ul_ccch_msg, msg->rrc_container, msg->rrc_container_length, 0, 0); if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { LOG_E(NR_RRC, " FATAL Error in receiving CCCH\n"); @@ -1517,7 +1523,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint AssertFatal(false, "not implemented\n"); } - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { /* TODO */ /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ @@ -1549,7 +1555,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint } else { LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", rnti, s_tmsi_part1); - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, s_tmsi_part1); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, s_tmsi_part1, msg->gNB_DU_ue_id); if (ue_context_p == NULL) { LOG_E(NR_RRC, "rrc_gNB_get_next_free_ue_context returned NULL\n"); return -1; @@ -1563,7 +1569,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint uint64_t random_value = 0; memcpy(((uint8_t *)&random_value) + 3, rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); LOG_E(NR_RRC, "RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE %04x\n", rnti); rrc_gNB_generate_RRCReject(module_id, ue_context_p); break; @@ -1575,8 +1581,8 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint rrc_gNB_generate_RRCSetup(module_id, rnti, rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti), - du_to_cu_rrc_container, - du_to_cu_rrc_container_len); + msg->du2cu_rrc_container, + msg->du2cu_rrc_container_length); } break; @@ -1585,7 +1591,11 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint break; case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: { - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(buffer), buffer_length, "[MSG] RRC Reestablishment Request\n"); + LOG_DUMPMSG(NR_RRC, + DEBUG_RRC, + (char *)(msg->rrc_container), + msg->rrc_container_length, + "[MSG] RRC Reestablishment Request\n"); rrcReestablishmentRequest = ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest; const NR_ReestablishmentCause_t cause = rrcReestablishmentRequest.reestablishmentCause; const long physCellId = rrcReestablishmentRequest.ue_Identity.physCellId; @@ -1662,7 +1672,11 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint // SRB2: set it to go through SRB1 with id 1 (DCCH) UE->Srb[2].Active = 1; protocol_ctxt_t ctxt = {.rntiMaybeUEid = rnti, .module_id = module_id, .instance = module_id, .enb_flag = 1, .eNB_index = module_id}; - rrc_gNB_generate_RRCReestablishment(&ctxt, ue_context_p, du_to_cu_rrc_container, gnb_rrc_inst->carrier.servingcellconfigcommon, 0); + rrc_gNB_generate_RRCReestablishment(&ctxt, + ue_context_p, + msg->du2cu_rrc_container, + gnb_rrc_inst->carrier.servingcellconfigcommon, + 0); LOG_I(NR_RRC, "CALLING RLC CONFIG SRB1 (rbid %d)\n", Idx); } break; @@ -2224,7 +2238,7 @@ void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t i = 0; LOG_W(RRC, "initial UL RRC message nr_cellid %ld does not match RRC's %ld\n", ul_rrc->nr_cellid, RC.nrrrc[0]->nr_cellid); } - nr_rrc_gNB_decode_ccch(i, ul_rrc->crnti, ul_rrc->rrc_container, ul_rrc->rrc_container_length, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length); + nr_rrc_gNB_decode_ccch(i, ul_rrc); if (ul_rrc->rrc_container) free(ul_rrc->rrc_container); diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 94123830d7..92c81a94bb 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -35,6 +35,7 @@ #include "common/utils/LOG/log.h" #include "rrc_gNB_UE_context.h" +#include "openair2/F1AP/f1ap_ids.h" //------------------------------------------------------------------------------ @@ -121,6 +122,7 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST *rrc_instance_pP, rrc_gNB_ue_context RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.rrc_ue_id - 1); + cu_remove_f1_ue_data(ue_context_pP->ue_context.cu_ue_id); rrc_gNB_free_mem_ue_context(ue_context_pP); LOG_I(NR_RRC, "Removed UE context\n"); } @@ -165,7 +167,10 @@ void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, } //----------------------------------------------------------------------------- // return a new ue context structure if ue_identityP, rnti not found in collection -rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP) +rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, + gNB_RRC_INST *rrc_instance_pP, + const uint64_t ue_identityP, + uint32_t du_ue_id) //----------------------------------------------------------------------------- { rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc_instance_pP, rnti); @@ -179,9 +184,22 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST *rrc_i if (ue_context_p == NULL) return NULL; - ue_context_p->ue_context.rnti = rnti; - ue_context_p->ue_context.random_ue_identity = ue_identityP; + gNB_RRC_UE_t *ue = &ue_context_p->ue_context; + ue->cu_ue_id = rnti; + ue->rnti = rnti; + ue->random_ue_identity = ue_identityP; + f1_ue_data_t ue_data = {.secondary_ue = du_ue_id}; + AssertFatal(!cu_exists_f1_ue_data(ue->cu_ue_id), + "UE F1 Context for ID %d already exists, logic bug\n", + ue->cu_ue_id); + cu_add_f1_ue_data(ue->cu_ue_id, &ue_data); + RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p); - LOG_W(NR_RRC, " Created new UE context rnti: %04x, random ue id %lx, RRC ue id %u\n", rnti, ue_identityP, ue_context_p->ue_context.rrc_ue_id); + LOG_I(NR_RRC, + "Created new UE context: CU UE ID %u DU UE ID %u (rnti: %04x, random ue id %lx)\n", + ue->cu_ue_id, + du_ue_id, + ue->rnti, + ue->random_ue_identity); return ue_context_p; } diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 9c1ec2c164..594b5d2957 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -51,6 +51,9 @@ rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI); void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, uint32_t gNB_ue_ngap_id); -rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); +rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, + gNB_RRC_INST* rrc_instance_pP, + const uint64_t ue_identityP, + uint32_t du_ue_id); #endif From 09438910054dc38e5b54867bdad02411af2a9c5f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 25 Jul 2023 12:06:37 +0200 Subject: [PATCH 28/47] Use CU/DU UE ID in DL RRC Message Transfer, manage at DU, refactor - The CU/DU UE ID is used in DL RRC Message Transfer - Note: The CU UE ID currently is still the RNTI - on every DL RRC Message, the DU verifies that the UE exists - Refactor RRC: common function to forward protected SRB PDUs --- openair2/COMMON/f1ap_messages_types.h | 3 +- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 11 ++-- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 13 ++--- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 30 +++++++++- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 13 ----- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h | 5 +- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 5 ++ openair2/RRC/NR/nr_rrc_proto.h | 3 + openair2/RRC/NR/rrc_gNB.c | 57 +++++++++++++------ openair2/RRC/NR/rrc_gNB_NGAP.c | 3 +- 10 files changed, 91 insertions(+), 52 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 08cc03c4fa..ea328c7671 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -286,8 +286,7 @@ typedef struct f1ap_dl_rrc_message_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; - uint32_t old_gNB_DU_ue_id; - uint16_t rnti; + uint32_t *old_gNB_DU_ue_id; uint8_t srb_id; uint8_t execute_duplication; uint8_t *rrc_container; diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 09c9633780..c91d662893 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -138,17 +138,18 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_dl_rrc->rnti); - LOG_D(F1AP, "Setting GNB_CU_UE_F1AP_ID %llu associated with UE RNTI %x (instance %ld)\n", - (unsigned long long int)ie1->value.choice.GNB_CU_UE_F1AP_ID, f1ap_dl_rrc->rnti, instance); + DevAssert(f1ap_dl_rrc->gNB_CU_ue_id != 0); + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_dl_rrc->gNB_CU_ue_id; + /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_dl_rrc->rnti); - LOG_D(F1AP, "GNB_DU_UE_F1AP_ID %llu associated with UE RNTI %x \n", (unsigned long long int)ie2->value.choice.GNB_DU_UE_F1AP_ID, f1ap_dl_rrc->rnti); + DevAssert(f1ap_dl_rrc->gNB_DU_ue_id != 0); + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_dl_rrc->gNB_DU_ue_id; + /* optional */ /* c3. oldgNB_DU_UE_F1AP_ID */ /* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) { diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index c694c3a227..76d6108386 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -60,8 +60,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_F1AP_PDU_t *pdu) { F1AP_DLRRCMessageTransfer_t *container; F1AP_DLRRCMessageTransferIEs_t *ie; - uint64_t cu_ue_f1ap_id; - uint64_t du_ue_f1ap_id; int executeDuplication; //uint64_t subscriberProfileIDforRFP; //uint64_t rAT_FrequencySelectionPriority; @@ -70,15 +68,11 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, /* GNB_CU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; - LOG_D(F1AP, "cu_ue_f1ap_id %lu \n", cu_ue_f1ap_id); + uint32_t cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; - LOG_D(F1AP, "du_ue_f1ap_id %lu associated with UE RNTI %x \n", - du_ue_f1ap_id, - f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id)); // this should be the one transmitted via initial ul rrc message transfer + uint32_t du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; if (f1ap_du_add_cu_ue_id(instance,du_ue_f1ap_id, cu_ue_f1ap_id) < 0 ) { LOG_E(F1AP, "Failed to find the F1AP UID \n"); @@ -135,9 +129,10 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } f1ap_dl_rrc_message_t dl_rrc = { + .gNB_CU_ue_id = cu_ue_f1ap_id, + .gNB_DU_ue_id = du_ue_f1ap_id, .rrc_container_length = ie->value.choice.RRCContainer.size, .rrc_container = ie->value.choice.RRCContainer.buf, - .rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id), .srb_id = srb_id }; dl_rrc_message_transfer(&dl_rrc); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 108c909c06..d47d28fe60 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -22,6 +22,7 @@ #include "mac_rrc_dl_handler.h" #include "mac_proto.h" +#include "openair2/F1AP/f1ap_ids.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/RRC/NR/MESSAGES/asn1_msg.h" @@ -266,12 +267,37 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) .rnti = cmd->rnti, }; mac->mac_rrc.ue_context_release_complete(&complete); + + du_remove_f1_ue_data(cmd->rnti); } void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) { - LOG_D(NR_MAC, "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", dl_rrc->rrc_container_length, dl_rrc->rnti, dl_rrc->srb_id); + LOG_D(NR_MAC, + "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", + dl_rrc->rrc_container_length, + dl_rrc->gNB_DU_ue_id, + dl_rrc->srb_id); + + gNB_MAC_INST *mac = RC.nrmac[0]; + pthread_mutex_lock(&mac->sched_lock); + /* check first that the scheduler knows such UE */ + NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, dl_rrc->gNB_DU_ue_id); + if (UE == NULL) { + LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring DL RRC Message Transfer\n", dl_rrc->gNB_DU_ue_id); + pthread_mutex_unlock(&mac->sched_lock); + return; + } + pthread_mutex_unlock(&mac->sched_lock); + + if (!du_exists_f1_ue_data(dl_rrc->gNB_DU_ue_id)) { + LOG_I(NR_MAC, "No CU UE ID stored for UE RNTI %04x, adding CU UE ID %d\n", dl_rrc->gNB_DU_ue_id, dl_rrc->gNB_CU_ue_id); + f1_ue_data_t new_ue_data = {.secondary_ue = dl_rrc->gNB_CU_ue_id}; + du_add_f1_ue_data(dl_rrc->gNB_DU_ue_id, &new_ue_data); + } + + AssertFatal(dl_rrc->old_gNB_DU_ue_id == NULL, "changing RNTI not implemented yet\n"); /* the DU ue id is the RNTI */ - nr_rlc_srb_recv_sdu(dl_rrc->rnti, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length); + nr_rlc_srb_recv_sdu(dl_rrc->gNB_DU_ue_id, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index f7fa3f1f78..1cb0c24aa0 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -740,19 +740,6 @@ void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock); } -void deliver_pdu_srb_f1(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, - char *buf, int size, int sdu_id) -{ - DevAssert(deliver_pdu_data != NULL); - gNB_RRC_INST *rrc = deliver_pdu_data; - f1ap_dl_rrc_message_t dl_rrc = {.old_gNB_DU_ue_id = 0xFFFFFF, - .rrc_container = (uint8_t *)buf, - .rrc_container_length = size, - .rnti = ue_id, - .srb_id = srb_id}; - rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); -} - static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_srb; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 0fd23d2f6b..64bb4ff3e6 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -80,10 +80,7 @@ bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP, typedef void (*deliver_pdu)(void *data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id); /* default implementation of deliver_pdu */ -void deliver_pdu_srb_rlc(void *data, ue_id_t ue_id, int srb_id, char *buf, - int size, int sdu_id); -void deliver_pdu_srb_f1(void *data, ue_id_t ue_id, int srb_id, char *buf, - int size, int sdu_id); +void deliver_pdu_srb_rlc(void *data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id); bool nr_pdcp_data_req_srb(ue_id_t ue_id, const rb_id_t rb_id, const mui_t muiP, diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 0aa9dbac35..3f3b0f800f 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -92,6 +92,11 @@ static void dl_rrc_message_transfer_f1ap(const f1ap_dl_rrc_message_t *dl_rrc) MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE); f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p); *msg = *dl_rrc; + if (dl_rrc->old_gNB_DU_ue_id) { + msg->old_gNB_DU_ue_id = malloc(sizeof(*msg->old_gNB_DU_ue_id)); + AssertFatal(msg->old_gNB_DU_ue_id != NULL, "out of memory\n"); + *msg->old_gNB_DU_ue_id = *dl_rrc->old_gNB_DU_ue_id; + } if (dl_rrc->rrc_container) { msg->rrc_container = malloc(dl_rrc->rrc_container_length); AssertFatal(msg->rrc_container != NULL, "out of memory\n"); diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index fd9f38a3fb..73cfb33c9d 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -172,4 +172,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id); + +void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size); + #endif diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 9b069b5b66..84f9363c4f 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -228,6 +228,29 @@ static void nr_rrc_addmod_drbs(int rnti, } } +typedef struct deliver_dl_rrc_message_data_s { + const gNB_RRC_INST *rrc; + f1ap_dl_rrc_message_t *dl_rrc; +} deliver_dl_rrc_message_data_t; +static void rrc_deliver_dl_rrc_message(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_dl_rrc_message_data_t *data = (deliver_dl_rrc_message_data_t *)deliver_pdu_data; + data->dl_rrc->rrc_container = (uint8_t *)buf; + data->dl_rrc->rrc_container_length = size; + DevAssert(data->dl_rrc->srb_id == srb_id); + data->rrc->mac_rrc.dl_rrc_message_transfer(data->dl_rrc); +} + + +void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size) +{ + DevAssert(size > 0); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->cu_ue_id); + f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->cu_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .srb_id = srb_id}; + deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; + nr_pdcp_data_req_srb(ue_p->cu_ue_id, srb_id, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); +} ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// @@ -471,11 +494,12 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, nr_pdcp_add_srbs(true, rnti, SRBs, 0, NULL, NULL); freeSRBlist(SRBs); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rnti); f1ap_dl_rrc_message_t dl_rrc = { - .old_gNB_DU_ue_id = 0xFFFFFF, + .gNB_CU_ue_id = ue_p->cu_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, .rrc_container = buf, .rrc_container_length = size, - .rnti = ue_p->rnti, .srb_id = CCCH }; rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); @@ -531,11 +555,12 @@ static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t m PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, rnti, 0, 0); apply_macrlc_config(rrc_instance_p, ue_context_pP, &ctxt); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rnti); f1ap_dl_rrc_message_t dl_rrc = { - .old_gNB_DU_ue_id = 0xFFFFFF, + .gNB_CU_ue_id = ue_p->cu_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, .rrc_container = buf, .rrc_container_length = size, - .rnti = ue_p->rnti, .srb_id = CCCH }; rrc_instance_p->mac_rrc.dl_rrc_message_transfer(&dl_rrc); @@ -560,13 +585,12 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context "[MSG] RRCReject \n"); LOG_I(NR_RRC, " [RAPROC] ue %04x Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", ue_p->rnti, size); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rnti); f1ap_dl_rrc_message_t dl_rrc = { - .gNB_CU_ue_id = 0, - .gNB_DU_ue_id = 0, - .old_gNB_DU_ue_id = 0xFFFFFF, + .gNB_CU_ue_id = ue_p->cu_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, .rrc_container = buf, .rrc_container_length = size, - .rnti = ue_p->rnti, .srb_id = CCCH, .execute_duplication = 1, .RAT_frequency_priority_information.en_dc = 0 @@ -674,7 +698,7 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co ue_context_pP->ue_context.rnti); AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; @@ -781,7 +805,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c ctxt_pP->module_id, DCCH); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, ue_context_pP->ue_context.masterCellGroup); @@ -934,7 +958,7 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( DCCH); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated @@ -1015,7 +1039,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( DCCH); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated @@ -1218,7 +1242,7 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, apply_macrlc_config_reest(rrc, ue_context_pP, ctxt_pP, ctxt_pP->rntiMaybeUEid); } - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); } /// @brief Function used in RRCReestablishmentComplete procedure to update the NGU Tunnels. @@ -1401,7 +1425,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx DCCH); nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, cellGroupConfig); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); } if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { @@ -1457,7 +1481,7 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, masterCellGroup); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated @@ -2912,7 +2936,8 @@ rrc_gNB_generate_UECapabilityEnquiry( gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + const gNB_RRC_UE_t *ue = &ue_context_pP->ue_context; + nr_rrc_transfer_protected_rrc_message(rrc, ue, DCCH, buffer, size); } 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) diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 517c1f31c2..0d0df4ec63 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -58,6 +58,7 @@ #include "NR_UE-CapabilityRAT-ContainerList.h" #include "NGAP_CauseRadioNetwork.h" #include "f1ap_messages_types.h" +#include "openair2/F1AP/f1ap_ids.h" #include "openair2/E1AP/e1ap_asnc.h" #include "NGAP_asn_constant.h" #include "NGAP_PDUSessionResourceSetupRequestTransfer.h" @@ -618,7 +619,7 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu AssertFatal(!NODE_IS_DU(RC.nrrrc[ctxt.module_id]->node_type), "illegal node type DU: receiving NGAP messages at this node\n"); /* Transfer data to PDCP */ rb_id_t srb_id = UE->Srb[2].Active ? DCCH1 : DCCH; - nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, (*rrc_gNB_mui)++, length, buffer, deliver_pdu_srb_f1, RC.nrrrc[instance]); + nr_rrc_transfer_protected_rrc_message(RC.nrrrc[instance], UE, srb_id, buffer, length); return 0; } From d220ee23e2c54a490f7088ac42fbf61d806a250b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 26 May 2023 16:36:28 +0200 Subject: [PATCH 29/47] UL RRC Message has CU/DU UE IDs --- openair2/COMMON/f1ap_messages_types.h | 3 ++- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 12 +++++++++++- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 18 +++++++++++------- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 7 ++++++- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 16 +++++++++++++--- openair2/RRC/NR/rrc_gNB.c | 3 ++- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index ea328c7671..16e67e2927 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -317,7 +317,8 @@ typedef struct f1ap_initial_ul_rrc_message_s { } f1ap_initial_ul_rrc_message_t; typedef struct f1ap_ul_rrc_message_s { - uint16_t rnti; + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; uint8_t srb_id; uint8_t *rrc_container; int rrc_container_length; diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index c91d662893..061b693d3e 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -32,6 +32,7 @@ #include "f1ap_common.h" #include "f1ap_encoder.h" +#include "f1ap_ids.h" #include "f1ap_itti_messaging.h" #include "f1ap_cu_rrc_message_transfer.h" #include "common/ran_context.h" @@ -253,6 +254,15 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; LOG_D(F1AP, "du_ue_f1ap_id %lu associated with RNTI %x\n", du_ue_f1ap_id, f1ap_get_rnti_by_cu_id(CUtype, instance, du_ue_f1ap_id)); + /* the RLC-PDCP does not transport the DU UE ID (yet), so we drop it here. + * For the moment, let's hope this won't become relevant; to sleep in peace, + * let's put an assert to check that it is the expected DU UE ID. */ + f1_ue_data_t ue_data = cu_get_f1_ue_data(cu_ue_f1ap_id); + AssertFatal(ue_data.secondary_ue == du_ue_f1ap_id, + "unexpected DU UE ID %d received, expected it to be %ld\n", + ue_data.secondary_ue, + du_ue_f1ap_id); + /* mandatory */ /* SRBID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, @@ -272,7 +282,7 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, protocol_ctxt_t ctxt={0}; ctxt.instance = instance; ctxt.module_id = instance; - ctxt.rntiMaybeUEid = f1ap_get_rnti_by_cu_id(CUtype, instance, cu_ue_f1ap_id); + ctxt.rntiMaybeUEid = cu_ue_f1ap_id; ctxt.enb_flag = 1; ctxt.eNB_index = 0; mem_block_t *mb = get_free_mem_block(ie->value.choice.RRCContainer.size,__func__); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 76d6108386..91e2c29f4b 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -220,15 +220,19 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_ini return 0; } -int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, - const f1ap_ul_rrc_message_t *msg) { - const rnti_t rnti = msg->rnti; +int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_ULRRCMessageTransfer_t *out; uint8_t *buffer = NULL; uint32_t len; - LOG_D(F1AP, "[DU %ld] %s: size %d UE RNTI %x in SRB %d\n", - instance, __func__, msg->rrc_container_length, rnti, msg->srb_id); + LOG_D(F1AP, + "[DU %ld] %s: size %d UE RNTI %x in SRB %d\n", + instance, + __func__, + msg->rrc_container_length, + msg->gNB_DU_ue_id, + msg->srb_id); //for (int i = 0;i < msg->rrc_container_length; i++) // printf("%02x ", msg->rrc_container[i]); //printf("\n"); @@ -246,14 +250,14 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; /* mandatory */ /* c3. SRBID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie3); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 1cb0c24aa0..32d8e4d0ed 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -36,6 +36,7 @@ #include "oai_asn1.h" #include "nr_pdcp_oai_api.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include "openair2/F1AP/f1ap_ids.h" #include #include "openair2/SDAP/nr_sdap/nr_sdap.h" #include "nr_pdcp_e1_api.h" @@ -710,7 +711,11 @@ srb_found: MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_GNB, 0, F1AP_UL_RRC_MESSAGE); AssertFatal(message_p != NULL, "OUT OF MEMORY\n"); f1ap_ul_rrc_message_t *ul_rrc = &F1AP_UL_RRC_MESSAGE(message_p); - ul_rrc->rnti = ue->rntiMaybeUEid; + ul_rrc->gNB_CU_ue_id = ue->rntiMaybeUEid; + /* look up the correct secondary UE ID to provide complete information to + * RRC, the RLC-PDCP interface does not transport this information */ + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rntiMaybeUEid); + ul_rrc->gNB_DU_ue_id = ue_data.secondary_ue; ul_rrc->srb_id = srb_id; ul_rrc->rrc_container = malloc(size); AssertFatal(ul_rrc->rrc_container != NULL, "OUT OF MEMORY\n"); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index f4097d721b..a22fe04b1b 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -39,6 +39,7 @@ #include "NR_UL-CCCH-Message.h" #include "openair2/F1AP/f1ap_du_rrc_message_transfer.h" +#include "openair2/F1AP/f1ap_ids.h" extern RAN_CONTEXT_t RC; @@ -425,11 +426,18 @@ rb_found: ctx.eNB_index = 0; ctx.brOption = 0; + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + /* used fields? */ ctx.module_id = 0; + /* CU (PDCP, RRC, SDAP) use a different ID than RNTI, so below set the CU UE + * ID if in gNB, else use RNTI normally */ ctx.rntiMaybeUEid = ue->rnti; + if (is_enb) { + f1_ue_data_t ue_data = du_get_f1_ue_data(ue->rnti); + ctx.rntiMaybeUEid = ue_data.secondary_ue; + } - is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); ctx.enb_flag = is_enb; if (is_enb) { @@ -453,7 +461,8 @@ rb_found: msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE); uint8_t *message_buffer = itti_malloc (TASK_RLC_ENB, TASK_DU_F1, size); memcpy (message_buffer, buf, size); - F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti; + F1AP_UL_RRC_MESSAGE(msg).gNB_CU_ue_id = ctx.rntiMaybeUEid; + F1AP_UL_RRC_MESSAGE(msg).gNB_DU_ue_id = ue->rnti; F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id; F1AP_UL_RRC_MESSAGE(msg).rrc_container = message_buffer; F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size; @@ -467,7 +476,7 @@ rb_found: memcpy(req->buffer,buf,size); req->length=size; req->offset=0; - req->ue_id=ue->rnti; + req->ue_id=ctx.rntiMaybeUEid; req->bearer_id=rb_id; LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size); extern instance_t DUuniqInstance; @@ -477,6 +486,7 @@ rb_found: } } + /* UE or monolithic gNB */ memblock = get_free_mem_block(size, __func__); if (memblock == NULL) { LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 84f9363c4f..986f37080f 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2754,7 +2754,7 @@ void *rrc_gnb_task(void *args_p) { PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, - F1AP_UL_RRC_MESSAGE(msg_p).rnti, + F1AP_UL_RRC_MESSAGE(msg_p).gNB_CU_ue_id, 0, 0); LOG_D(NR_RRC, @@ -2764,6 +2764,7 @@ void *rrc_gnb_task(void *args_p) { instance, &ctxt, F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length); + DevAssert(F1AP_UL_RRC_MESSAGE(msg_p).gNB_CU_ue_id == F1AP_UL_RRC_MESSAGE(msg_p).gNB_DU_ue_id); rrc_gNB_decode_dcch(&ctxt, F1AP_UL_RRC_MESSAGE(msg_p).srb_id, F1AP_UL_RRC_MESSAGE(msg_p).rrc_container, From d24454ce9af66f43f06f762c9f0a3fb0d514474f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 31 May 2023 06:29:34 +0200 Subject: [PATCH 30/47] UE Context setup and modif --- openair2/COMMON/f1ap_messages_types.h | 3 +- openair2/F1AP/f1ap_cu_ue_context_management.c | 19 +++---- openair2/F1AP/f1ap_du_ue_context_management.c | 34 +++-------- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 22 ++++--- .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 1 - openair2/RRC/NR/rrc_gNB.c | 57 ++++++++++--------- 6 files changed, 57 insertions(+), 79 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 16e67e2927..91dd1a35d8 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -378,9 +378,8 @@ typedef enum ReconfigurationCompl_e { } ReconfigurationCompl_t; typedef struct f1ap_ue_context_setup_s { - uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti + uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; - uint16_t rnti; // SpCell Info uint16_t mcc; uint16_t mnc; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index cd5eb0ae95..ad452e4fac 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -82,7 +82,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_ue_context_setup_req->rnti); //f1ap_ue_context_setup_req->gNB_CU_ue_id; + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_CU_ue_id; /* optional */ /* c2. GNB_DU_UE_F1AP_ID */ @@ -91,7 +91,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_ignore; ie2->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_ue_context_setup_req->rnti); //*f1ap_ue_context_setup_req->gNB_DU_ue_id; + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_DU_ue_id; } /* mandatory */ @@ -510,7 +510,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* 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(CUtype, instance)->gtpInst, - f1ap_ue_context_setup_req->rnti, + f1ap_ue_context_setup_req->gNB_DU_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 @@ -654,8 +654,6 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); f1ap_ue_context_setup_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_setup_resp->gNB_DU_ue_id); - f1ap_ue_context_setup_resp->rnti = - f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_setup_resp->gNB_DU_ue_id); // DUtoCURRCInformation F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, true); @@ -695,7 +693,7 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, 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(CUtype, instance)->gtpInst, - f1ap_ue_context_setup_resp->rnti, + 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); @@ -1002,14 +1000,14 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);; + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);; + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_DU_ue_id; /* optional */ /* c3. NRCGI */ @@ -1618,9 +1616,6 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, LOG_D(F1AP, "f1ap_ue_context_modification_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id); - f1ap_ue_context_modification_resp->rnti = - f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_modification_resp->gNB_DU_ue_id); - // DUtoCURRCInformation F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, false); @@ -1656,7 +1651,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, 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(CUtype, instance)->gtpInst, - f1ap_ue_context_modification_resp->rnti, + f1ap_ue_context_modification_resp->gNB_DU_ue_id, (ebi_t)drbs_setupmod_item_p->dRBID, drb_p->up_dl_tnl[0].tl_address, drb_p->up_dl_tnl[0].teid); diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 05833e3fad..cf3b1103ff 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -77,21 +77,8 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* GNB_DU_UE_F1AP_ID */ F1AP_UEContextSetupRequestIEs_t *ieDU_UE; F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieDU_UE, container, - F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, false); - - if (ieDU_UE) { - f1ap_ue_context_setup_req->gNB_DU_ue_id = - ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID; - f1ap_ue_context_setup_req->rnti = - f1ap_get_rnti_by_du_id(DUtype, instance, f1ap_ue_context_setup_req->gNB_DU_ue_id); - } else { - f1ap_ue_context_setup_req->gNB_DU_ue_id = -1; - f1ap_ue_context_setup_req->rnti = - f1ap_get_rnti_by_cu_id(DUtype, instance, f1ap_ue_context_setup_req->gNB_CU_ue_id); - } - - if(f1ap_ue_context_setup_req->rnti<0) - LOG_E(F1AP, "Could not retrieve UE rnti based on the CU/DU UE id \n"); + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + f1ap_ue_context_setup_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID; /* SpCell_ID */ F1AP_UEContextSetupRequestIEs_t *ieNet; @@ -247,7 +234,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = resp->gNB_DU_ue_id; /* mandatory */ /* c3. DUtoCURRCInformation */ @@ -285,7 +272,8 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup ie4->criticality = F1AP_Criticality_ignore; ie4->value.present = F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI; //C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI); - ie4->value.choice.C_RNTI=resp->rnti; + ie4->value.choice.C_RNTI=0; + AssertFatal(false, "not implemented\n"); LOG_E(F1AP,"RNTI to code!\n"); } @@ -825,12 +813,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t asso F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDU_UE, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); f1ap_ue_context_modification_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID; - f1ap_ue_context_modification_req->rnti = f1ap_get_rnti_by_du_id(DUtype, instance, f1ap_ue_context_modification_req->gNB_DU_ue_id); - - if(f1ap_ue_context_modification_req->rnti<0) - LOG_E(F1AP, "Could not retrieve UE rnti based on the DU UE id \n"); - else - LOG_D(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti); /* SRB */ F1AP_UEContextModificationRequestIEs_t *ieSrb; @@ -944,7 +926,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t asso ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); protocol_ctxt_t ctxt; // decode RRC Container and act on the message type - ctxt.rntiMaybeUEid = f1ap_ue_context_modification_req->rnti; + ctxt.rntiMaybeUEid = f1ap_ue_context_modification_req->gNB_DU_ue_id; ctxt.instance = instance; ctxt.module_id = instance; ctxt.enb_flag = 1; @@ -991,7 +973,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = resp->gNB_DU_ue_id; /* optional */ /* c3. ResourceCoordinationTransferContainer */ @@ -1057,7 +1039,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex 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(false, instance)->gtpInst, - resp->rnti, + resp->gNB_DU_ue_id, drb->drb_id, drb->drb_id, drb->up_ul_tnl[j].teid, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index d47d28fe60..7ef3e5ba2f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -101,7 +101,6 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) f1ap_ue_context_setup_t resp = { .gNB_CU_ue_id = req->gNB_CU_ue_id, .gNB_DU_ue_id = req->gNB_DU_ue_id, - .rnti = req->rnti, }; if (req->cu_to_du_rrc_information != NULL) { @@ -112,11 +111,11 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) NR_SCHED_LOCK(&mac->sched_lock); - NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti); - AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->rnti); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->gNB_DU_ue_id); + AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->gNB_DU_ue_id); if (req->srbs_to_be_setup_length > 0) { - resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti, + resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->gNB_DU_ue_id, req->srbs_to_be_setup_length, req->srbs_to_be_setup, &resp.srbs_to_be_setup, @@ -124,7 +123,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) } if (req->drbs_to_be_setup_length > 0) { - resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti, + resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->gNB_DU_ue_id, req->drbs_to_be_setup_length, req->drbs_to_be_setup, &resp.drbs_to_be_setup, @@ -132,7 +131,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) } if (req->rrc_container != NULL) - nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length); + nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length); //nr_mac_update_cellgroup() resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); @@ -172,7 +171,6 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) f1ap_ue_context_modif_resp_t resp = { .gNB_CU_ue_id = req->gNB_CU_ue_id, .gNB_DU_ue_id = req->gNB_DU_ue_id, - .rnti = req->rnti, }; if (req->cu_to_du_rrc_information != NULL) { @@ -182,10 +180,10 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) } NR_SCHED_LOCK(&mac->sched_lock); - NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->gNB_DU_ue_id); if (req->srbs_to_be_setup_length > 0) { - resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti, + resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->gNB_DU_ue_id, req->srbs_to_be_setup_length, req->srbs_to_be_setup, &resp.srbs_to_be_setup, @@ -193,7 +191,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) } if (req->drbs_to_be_setup_length > 0) { - resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti, + resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->gNB_DU_ue_id, req->drbs_to_be_setup_length, req->drbs_to_be_setup, &resp.drbs_to_be_setup, @@ -201,7 +199,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) } if (req->rrc_container != NULL) - nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length); + nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length); if (req->ReconfigComplOutcome != RRCreconf_info_not_present && req->ReconfigComplOutcome != RRCreconf_success) { LOG_E(NR_MAC, @@ -225,7 +223,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; /* works? */ - nr_mac_update_cellgroup(RC.nrmac[0], req->rnti, UE->CellGroup); + nr_mac_update_cellgroup(RC.nrmac[0], req->gNB_DU_ue_id, UE->CellGroup); } NR_SCHED_UNLOCK(&mac->sched_lock); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index 6780fad873..a024abe6af 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -64,7 +64,6 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_ f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id; f1ap_msg->gNB_DU_ue_id = resp->gNB_DU_ue_id; - f1ap_msg->rnti = resp->rnti; f1ap_msg->mcc = resp->mcc; f1ap_msg->mnc = resp->mnc; f1ap_msg->mnc_digit_length = resp->mnc_digit_length; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 986f37080f..b030718169 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2002,10 +2002,10 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ } gNB_RRC_INST *rrc = RC.nrrrc[0]; + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rnti); f1ap_ue_context_modif_req_t ue_context_modif_req = { - .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .rnti = UE->rnti, + .gNB_CU_ue_id = UE->cu_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, .mcc = rrc->configuration.mcc[0], .mnc = rrc->configuration.mnc[0], .mnc_digit_length = rrc->configuration.mnc_digit_length[0], @@ -2286,7 +2286,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance { f1ap_ue_context_setup_t *resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->gNB_CU_ue_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; NR_CellGroupConfig_t *cellGroupConfig = NULL; @@ -2343,9 +2343,9 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance) { f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); - protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; + protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->gNB_CU_ue_id, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->gNB_CU_ue_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (resp->drbs_to_be_setup_length > 0) { @@ -2601,10 +2601,10 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex srbs[0].lcid = 2; } + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rnti); f1ap_ue_context_modif_req_t ue_context_modif_req = { - .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .rnti = UE->rnti, + .gNB_CU_ue_id = UE->cu_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, .mcc = rrc->configuration.mcc[0], .mnc = rrc->configuration.mnc[0], .mnc_digit_length = rrc->configuration.mnc_digit_length[0], @@ -2868,25 +2868,17 @@ void *rrc_gnb_task(void *args_p) { } } +typedef struct deliver_ue_ctxt_setup_data_t { + gNB_RRC_INST *rrc; + f1ap_ue_context_setup_t *setup_req; +} deliver_ue_ctxt_setup_data_t; static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { DevAssert(deliver_pdu_data != NULL); - gNB_RRC_INST *rrc = deliver_pdu_data; - f1ap_ue_context_setup_t ue_context_setup_req = { - .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .rnti = ue_id, - .mcc = rrc->configuration.mcc[0], - .mnc = rrc->configuration.mnc[0], - .mnc_digit_length = rrc->configuration.mnc_digit_length[0], - .nr_cellid = rrc->nr_cellid, - .servCellId = 0, /* TODO: correct value? */ - .srbs_to_be_setup = 0, /* no new SRBs */ - .drbs_to_be_setup = 0, /* no new DRBs */ - .rrc_container = (uint8_t*) buf, /* security mode command */ - .rrc_container_length = size, - }; - rrc->mac_rrc.ue_context_setup_request(&ue_context_setup_req); + deliver_ue_ctxt_setup_data_t *data = deliver_pdu_data; + data->setup_req->rrc_container = (uint8_t*)buf; + data->setup_req->rrc_container_length = size; + data->rrc->mac_rrc.ue_context_setup_request(data->setup_req); } //----------------------------------------------------------------------------- @@ -2911,7 +2903,20 @@ rrc_gNB_generate_SecurityModeCommand( AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); /* the callback will fill the UE context setup request and forward it */ - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, rrc); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rnti); + f1ap_ue_context_setup_t ue_context_setup_req = { + .gNB_CU_ue_id = ue_p->cu_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, + .mcc = rrc->configuration.mcc[0], + .mnc = rrc->configuration.mnc[0], + .mnc_digit_length = rrc->configuration.mnc_digit_length[0], + .nr_cellid = rrc->nr_cellid, + .servCellId = 0, /* TODO: correct value? */ + .srbs_to_be_setup = 0, /* no new SRBs */ + .drbs_to_be_setup = 0, /* no new DRBs */ + }; + deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req}; + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, &data); } void From f48d86d7c5bedbea49214c02ab38d677736e65e3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 31 May 2023 06:59:19 +0200 Subject: [PATCH 31/47] UE Ctxt Release Req/Cmd/Complete --- openair2/COMMON/f1ap_messages_types.h | 3 +- openair2/F1AP/f1ap_cu_ue_context_management.c | 13 ++----- openair2/F1AP/f1ap_du_ue_context_management.c | 16 ++++---- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 5 ++- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 13 ++++--- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 2 +- openair2/RRC/NR/rrc_gNB.c | 39 +++++++++++-------- 7 files changed, 47 insertions(+), 44 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 91dd1a35d8..3d594a695e 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -418,7 +418,8 @@ typedef enum F1ap_Cause_e { } f1ap_Cause_t; typedef struct f1ap_ue_context_release_s { - uint16_t rnti; + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; f1ap_Cause_t cause; long cause_value; uint8_t *rrc_container; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index ad452e4fac..a3f0763a77 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -784,17 +784,12 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, uint32_t assoc_id, /* GNB_CU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - const rnti_t rnti = f1ap_get_rnti_by_cu_id(true, instance, - ie->value.choice.GNB_CU_UE_F1AP_ID); - req->rnti = rnti; + req->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - const rnti_t rnti2 = f1ap_get_rnti_by_du_id(CUtype, instance, - ie->value.choice.GNB_DU_UE_F1AP_ID); - AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", - rnti2, rnti); + req->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; /* Cause */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, @@ -855,14 +850,14 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, cmd->rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = cmd->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, cmd->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = cmd->gNB_DU_ue_id; /* mandatory */ /* c3. Cause */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie3); diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index cf3b1103ff..63a40fcb33 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -574,14 +574,14 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, req->rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = req->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseRequestIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, req->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = req->gNB_DU_ue_id; /* mandatory */ /* c3. Cause */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseRequestIEs_t, ie3); @@ -642,13 +642,11 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, uint32_t assoc_id, // GNB_CU_UE_F1AP_ID F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - f1ap_ue_context_release_cmd->rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); + f1ap_ue_context_release_cmd->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; // GNB_DU_UE_F1AP_ID F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - const rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance, - ie->value.choice.GNB_DU_UE_F1AP_ID); - AssertFatal(f1ap_ue_context_release_cmd->rnti == rnti, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", rnti, f1ap_ue_context_release_cmd->rnti); + f1ap_ue_context_release_cmd->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; // We don't need the Cause // Optional RRC Container: if present, send to UE @@ -709,14 +707,14 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, complete->rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = complete->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list,F1AP_UEContextReleaseCompleteIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, complete->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = complete->gNB_DU_ue_id; /* optional -> currently not used */ /* c3. CriticalityDiagnostics */ //if (0) { @@ -778,7 +776,7 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel buffer, len, getCxt(false, instance)->default_sctp_stream_id); - f1ap_remove_ue(DUtype, instance, complete->rnti); + f1ap_remove_ue(DUtype, instance, complete->gNB_DU_ue_id); return 0; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 3f68575c15..81ea2edcb7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -47,6 +47,7 @@ #include "RRC/NR/MESSAGES/asn1_msg.h" #include "intertask_interface.h" +#include "openair2/F1AP/f1ap_ids.h" #include "T.h" @@ -2983,8 +2984,10 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct /* to trigger only once: trigger when ul_failure_timer == 1, but timer will * stop at 0 and we wait for a UE release command from upper layers */ if (sched_ctrl->ul_failure_timer == 1) { + f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); f1ap_ue_context_release_complete_t complete = { - .rnti = rnti, + .gNB_CU_ue_id = ue_data.secondary_ue, + .gNB_DU_ue_id = rnti, .cause = F1AP_CAUSE_RADIO_NETWORK, .cause_value = 12, // F1AP_CauseRadioNetwork_rl_failure_others }; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 7ef3e5ba2f..ee66931475 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -248,25 +248,26 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) /* mark UE as to be deleted after PUSCH failure */ gNB_MAC_INST *mac = RC.nrmac[0]; pthread_mutex_lock(&mac->sched_lock); - NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->rnti); + NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, 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_rlc_remove_ue(cmd->rnti); - mac_remove_nr_ue(mac, cmd->rnti); + nr_rlc_remove_ue(cmd->gNB_DU_ue_id); + mac_remove_nr_ue(mac, cmd->gNB_DU_ue_id); } else { /* UE is in sync: forward release message and mark to be deleted * after UL failure */ - nr_rlc_srb_recv_sdu(cmd->rnti, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length); + nr_rlc_srb_recv_sdu(cmd->gNB_DU_ue_id, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length); nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); } pthread_mutex_unlock(&mac->sched_lock); f1ap_ue_context_release_complete_t complete = { - .rnti = cmd->rnti, + .gNB_CU_ue_id = cmd->gNB_CU_ue_id, + .gNB_DU_ue_id = cmd->gNB_DU_ue_id, }; mac->mac_rrc.ue_context_release_complete(&complete); - du_remove_f1_ue_data(cmd->rnti); + du_remove_f1_ue_data(cmd->gNB_DU_ue_id); } void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index f122a13c34..644decc21c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -106,7 +106,7 @@ static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* static void ue_context_release_complete_f1ap(const f1ap_ue_context_release_complete_t *complete) { - newGtpuDeleteAllTunnels(0, complete->rnti); + newGtpuDeleteAllTunnels(0, complete->gNB_DU_ue_id); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index b030718169..5c8700ce41 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2315,10 +2315,10 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p) const int instance = 0; f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->gNB_CU_ue_id); //here /* TODO: marshall types correctly */ - LOG_I(NR_RRC, "received UE Context Release Request for UE %04x, forwarding to AMF\n", req->rnti); + LOG_I(NR_RRC, "received UE Context Release Request for UE %u, forwarding to AMF\n", req->gNB_CU_ue_id); rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(instance, ue_context_p, NGAP_CAUSE_RADIO_NETWORK, @@ -2330,7 +2330,7 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) const int instance = 0; f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, complete->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, complete->gNB_CU_ue_id); // here gNB_RRC_UE_t *UE = &ue_context_p->ue_context; nr_pdcp_remove_UE(UE->rnti); @@ -2946,22 +2946,17 @@ 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; +} 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); - gNB_RRC_INST *rrc = deliver_pdu_data; - uint8_t *rrc_container = malloc(size); - AssertFatal(rrc_container != NULL, "out of memory\n"); - memcpy(rrc_container, buf, size); - f1ap_ue_context_release_cmd_t ue_context_release_cmd = { - .rnti = ue_id, /* TODO: proper IDs! */ - .cause = F1AP_CAUSE_RADIO_NETWORK, - .cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release - .srb_id = srb_id, - .rrc_container = rrc_container, - .rrc_container_length = size, - }; - rrc->mac_rrc.ue_context_release_command(&ue_context_release_cmd); + 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->release_cmd); } //----------------------------------------------------------------------------- @@ -2985,7 +2980,17 @@ rrc_gNB_generate_RRCRelease( size); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, rrc); + const gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rnti); + f1ap_ue_context_release_cmd_t ue_context_release_cmd = { + .gNB_CU_ue_id = UE->cu_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, + .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(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data); /* UE will be freed after UE context release complete */ } From 7c2c01727e72918321c75c721821d7dd5fe4105c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 31 May 2023 07:25:16 +0200 Subject: [PATCH 32/47] Send ue ITTI Release Complete message Previously, the F1AP handler called various functions directly, instead of sending an ITTI message to the RRC thread. This has two drawbacks: - it can lead to data races if the RRC task uses functionality that is being accessed by the F1 task through this function - no homogeneity: all other handlers send an ITTI message, so this one should too --- openair2/F1AP/f1ap_cu_ue_context_management.c | 29 ++++--------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index a3f0763a77..e742510d67 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -926,19 +926,18 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, F1AP_UEContextReleaseComplete_t *container; F1AP_UEContextReleaseCompleteIEs_t *ie; DevAssert(pdu); + MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextReleaseComplete; /* GNB_CU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - const rnti_t rnti = f1ap_get_rnti_by_cu_id(CUtype, instance, - ie->value.choice.GNB_CU_UE_F1AP_ID); + complete->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - const rnti_t rnti2 = f1ap_get_rnti_by_du_id(CUtype, instance, - ie->value.choice.GNB_DU_UE_F1AP_ID); - AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", - rnti2, rnti); + complete->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + /* Optional*/ /* CriticalityDiagnostics */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container, @@ -952,24 +951,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, // F1AP_CriticalityDiagnostics_IE_List } - protocol_ctxt_t ctxt; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, GNB_FLAG_YES, rnti, 0, 0, instance); + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], rnti); - - if (ue_context_p) { - MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE); - NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.rrc_ue_id; - itti_send_msg_to_task(TASK_NGAP, instance, msg); - rrc_gNB_remove_ue_context(RC.nrrrc[instance], ue_context_p); - } else { - LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti); - } - - nr_pdcp_remove_UE(ctxt.rntiMaybeUEid); - - LOG_I(F1AP, "Received UE CONTEXT RELEASE COMPLETE: Removing CU UE entry for RNTI %x\n", rnti); - f1ap_remove_ue(CUtype, instance, rnti); return 0; } From eca89e20b06de7d9fe6d0033780ff80fc126692e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 31 May 2023 07:25:35 +0200 Subject: [PATCH 33/47] Remove F1 module UE handling The UE had a list of known UEs. With the introduction of a separate module for F1 UE ID handling that is also used in monolithic (to separate CU UE ID from DU UE ID), this functionality is not needed, and deleted in this commit. --- openair2/F1AP/f1ap_common.c | 117 ------------------ openair2/F1AP/f1ap_common.h | 24 ---- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 11 -- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 11 -- openair2/F1AP/f1ap_du_ue_context_management.c | 1 - 5 files changed, 164 deletions(-) diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c index f417a1c337..f396d570df 100644 --- a/openair2/F1AP/f1ap_common.c +++ b/openair2/F1AP/f1ap_common.c @@ -66,123 +66,6 @@ void createF1inst(F1_t isCU, instance_t instanceP, f1ap_setup_req_t *req) { } } -int f1ap_add_ue(F1_t isCu, - instance_t instanceP, - rnti_t rntiP) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == rntiP) { - f1_inst->f1ap_ue[i].f1ap_uid = i; - LOG_I(F1AP, "Updating the index of UE with RNTI %x and du_ue_f1ap_id %ld\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id); - return i; - } - } - - // We didn't find the rnti - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == 0 ) { - f1_inst->f1ap_ue[i].rnti = rntiP; - f1_inst->f1ap_ue[i].f1ap_uid = i; - f1_inst->f1ap_ue[i].du_ue_f1ap_id = rntiP; - f1_inst->f1ap_ue[i].cu_ue_f1ap_id = rntiP; - f1_inst->num_ues++; - LOG_I(F1AP, "Adding a new UE with RNTI %x and cu/du ue_f1ap_id %ld\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id); - return i; - } - } - - return -1; -} - - -int f1ap_remove_ue(F1_t isCu, instance_t instanceP, - rnti_t rntiP) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == rntiP) { - f1_inst->f1ap_ue[i].rnti = 0; - break; - } - } - - f1_inst->num_ues--; - return 0; -} - -int f1ap_get_du_ue_f1ap_id(F1_t isCu, instance_t instanceP, - rnti_t rntiP) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == rntiP) { - return f1_inst->f1ap_ue[i].du_ue_f1ap_id; - } - } - - return -1; -} - -int f1ap_get_cu_ue_f1ap_id(F1_t isCu, instance_t instanceP, - rnti_t rntiP) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == rntiP) { - return f1_inst->f1ap_ue[i].cu_ue_f1ap_id; - } - } - - return -1; -} - -int f1ap_get_rnti_by_du_id(F1_t isCu, instance_t instanceP, - instance_t du_ue_f1ap_id ) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) { - return f1_inst->f1ap_ue[i].rnti; - } - } - - return -1; -} - -int f1ap_get_rnti_by_cu_id(F1_t isCu, instance_t instanceP, - instance_t cu_ue_f1ap_id ) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].cu_ue_f1ap_id == cu_ue_f1ap_id) { - return f1_inst->f1ap_ue[i].rnti; - } - } - - return -1; -} - -int f1ap_du_add_cu_ue_id(instance_t instanceP, - instance_t du_ue_f1ap_id, - instance_t cu_ue_f1ap_id) { - f1ap_cudu_inst_t *f1_inst=getCxt(DUtype, instanceP); - instance_t f1ap_uid=-1; - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) { - f1ap_uid=i; - break; - } - } - - if (f1ap_uid < 0 || f1ap_uid >= MAX_MOBILES_PER_GNB) - return -1; - - f1_inst->f1ap_ue[f1ap_uid].cu_ue_f1ap_id = cu_ue_f1ap_id; - LOG_D(F1AP, "Adding cu_ue_f1ap_id %ld for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti); - return 0; -} int f1ap_assoc_id(F1_t isCu, instance_t instanceP) { f1ap_setup_req_t *f1_inst=f1ap_req(isCu, instanceP); diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h index ff492820d7..a346d9682a 100644 --- a/openair2/F1AP/f1ap_common.h +++ b/openair2/F1AP/f1ap_common.h @@ -427,30 +427,6 @@ uint8_t F1AP_get_next_transaction_identifier(instance_t mod_idP, instance_t cu_m f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP); void createF1inst(F1_t isCU, instance_t instanceP, f1ap_setup_req_t *req); -int f1ap_add_ue(F1_t isCu, - instance_t instanceP, - rnti_t rntiP); - -int f1ap_remove_ue(F1_t isCu, instance_t instanceP, - rnti_t rntiP); - -int f1ap_get_du_ue_f1ap_id (F1_t isCu, instance_t instanceP, - rnti_t rntiP); - -int f1ap_get_cu_ue_f1ap_id (F1_t isCu, instance_t instanceP, - rnti_t rntiP); - - -int f1ap_get_rnti_by_du_id(F1_t isCu, instance_t instanceP, - instance_t du_ue_f1ap_id ); - - -int f1ap_get_rnti_by_cu_id(F1_t isCu, instance_t instanceP, - instance_t cu_ue_f1ap_id ); - -int f1ap_du_add_cu_ue_id(instance_t instanceP, - instance_t du_ue_f1ap_id, - instance_t cu_ue_f1ap_id); int f1ap_assoc_id(F1_t isCu, instance_t instanceP); diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 061b693d3e..12e0d96c14 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -88,13 +88,6 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, du2cu, container, F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false); - int f1ap_uid = f1ap_add_ue(CUtype, instance, rnti); - - if (f1ap_uid < 0 ) { - LOG_E(F1AP, "Failed to add UE \n"); - return -1; - } - // create an ITTI message and copy SDU AssertFatal(f1ap_req(true, instance)->cell_type == CELL_MACRO_GNB, "illegal cell type %d\n", f1ap_req(true, instance)->cell_type); message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); @@ -246,14 +239,10 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; - LOG_D(F1AP, "cu_ue_f1ap_id %lu associated with RNTI %x\n", - cu_ue_f1ap_id, f1ap_get_rnti_by_cu_id(CUtype, instance, cu_ue_f1ap_id)); /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; - LOG_D(F1AP, "du_ue_f1ap_id %lu associated with RNTI %x\n", - du_ue_f1ap_id, f1ap_get_rnti_by_cu_id(CUtype, instance, du_ue_f1ap_id)); /* the RLC-PDCP does not transport the DU UE ID (yet), so we drop it here. * For the moment, let's hope this won't become relevant; to sleep in peace, * let's put an assert to check that it is the expected DU UE ID. */ diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 91e2c29f4b..dfe33ef1ab 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -74,11 +74,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); uint32_t du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; - if (f1ap_du_add_cu_ue_id(instance,du_ue_f1ap_id, cu_ue_f1ap_id) < 0 ) { - LOG_E(F1AP, "Failed to find the F1AP UID \n"); - //return -1; - } - /* optional */ /* oldgNB_DU_UE_F1AP_ID */ if (0) { @@ -146,12 +141,6 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_ini F1AP_InitialULRRCMessageTransfer_t *out; uint8_t *buffer=NULL; uint32_t len=0; - int f1ap_uid = f1ap_add_ue(DUtype, instanceP, msg->crnti); - - if (f1ap_uid < 0 ) { - LOG_E(F1AP, "Failed to add UE \n"); - return -1; - } /* Create */ /* 0. Message Type */ diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 63a40fcb33..2430b2f870 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -776,7 +776,6 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel buffer, len, getCxt(false, instance)->default_sctp_stream_id); - f1ap_remove_ue(DUtype, instance, complete->gNB_DU_ue_id); return 0; } From 2e1107fa417633204af5c1c24bde4ee44e6289d9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 4 Jul 2023 19:06:18 +0200 Subject: [PATCH 34/47] Refactor PDCP: DRB callback for gNB to look up IDs --- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 32 ++++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 32d8e4d0ed..6f6c2352a4 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -654,11 +654,24 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, } } -static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, - char *buf, int size, int sdu_id) +static void deliver_pdu_drb_ue(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, + char *buf, int size, int sdu_id) { DevAssert(deliver_pdu_data == NULL); - protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_id }; + protocol_ctxt_t ctxt = { .enb_flag = 0, .rntiMaybeUEid = ue_id }; + + mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__); + memcpy(memblock->data, buf, size); + LOG_D(PDCP, "%s(): (drb %d) calling rlc_data_req size %d UE %ld/%04lx\n", __func__, rb_id, size, ctxt.rntiMaybeUEid, ctxt.rntiMaybeUEid); + enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock); +} + +static void deliver_pdu_drb_gnb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, + char *buf, int size, int sdu_id) +{ + DevAssert(deliver_pdu_data == NULL); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id); + protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_data.secondary_ue }; if (NODE_IS_CU(node_type)) { MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0, @@ -669,12 +682,11 @@ static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, AssertFatal(message_p != NULL, "OUT OF MEMORY"); gtpv1u_tunnel_data_req_t *req=>PV1U_TUNNEL_DATA_REQ(message_p); uint8_t *gtpu_buffer_p = (uint8_t*)(req+1); - memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX, - buf, size); + memcpy(gtpu_buffer_p + GTPU_HEADER_OVERHEAD_MAX, buf, size); req->buffer = gtpu_buffer_p; req->length = size; req->offset = GTPU_HEADER_OVERHEAD_MAX; - req->ue_id = ue_id; + req->ue_id = ctxt.rntiMaybeUEid; req->bearer_id = rb_id; LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); extern instance_t CUuniqInstance; @@ -683,8 +695,6 @@ static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__); memcpy(memblock->data, buf, size); LOG_D(PDCP, "%s(): (drb %d) calling rlc_data_req size %d\n", __func__, rb_id, size); - //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]); - //printf("\n"); enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock); } } @@ -852,8 +862,10 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st LOG_W(PDCP, "%s:%d:%s: warning DRB %d already exist for UE ID/RNTI %ld, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rntiMaybeUEid); } else { pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id, pdusession_id, - has_sdap_rx, has_sdap_tx, - deliver_sdu_drb, ue, deliver_pdu_drb, ue, + has_sdap_rx, has_sdap_tx, deliver_sdu_drb, ue, + is_gnb ? + deliver_pdu_drb_gnb : deliver_pdu_drb_ue, + ue, sn_size_dl, t_reordering, discard_timer, has_ciphering ? ciphering_algorithm : 0, has_integrity ? integrity_algorithm : 0, From c832b7af91e3d77e361c2bb005fa03540f75b7f7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 6 Jul 2023 19:04:07 +0200 Subject: [PATCH 35/47] Configure CU/DU UE IDs in NSA/do-ra/phytest --- openair2/RRC/NR/rrc_gNB_nsa.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index ddfc1fae38..1cceb3ec1f 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -41,6 +41,7 @@ #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" +#include "openair2/F1AP/f1ap_ids.h" #include "executables/softmodem-common.h" #include "executables/nr-softmodem.h" #include @@ -342,19 +343,30 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding } + // below we configure the stack. In SA, we fully adopted F1, meaning that + // layers use different IDs (MAC/RLC use RNTI as DU UE ID, above use NGAP ID + // as CU UE ID. + uint32_t du_ue_id = ue_context_p->ue_context.rnti; + uint32_t cu_ue_id = ue_context_p->ue_context.rnti; + f1_ue_data_t du_ue_data = {.secondary_ue = cu_ue_id}; + du_add_f1_ue_data(du_ue_id, &du_ue_data); + f1_ue_data_t cu_ue_data = {.secondary_ue = du_ue_id}; + cu_add_f1_ue_data(cu_ue_id, &cu_ue_data); + LOG_I(RRC, "Assign CU UE ID %d and DU UE ID %d to UE RNTI %04x\n", cu_ue_id, du_ue_id, ue_context_p->ue_context.rnti); + // configure MAC and RLC bool ret = false; if (get_softmodem_params()->phy_test) { // phytest mode: we don't set up RA, etc - ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id] , ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup); + ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup); } else { NR_SCHED_LOCK(&RC.nrmac[rrc->module_id]->sched_lock); - ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup); + ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup); NR_SCHED_UNLOCK(&RC.nrmac[rrc->module_id]->sched_lock); } AssertFatal(ret, "cannot add NSA UE in MAC, aborting\n"); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, cu_ue_id, 0, 0, rrc->module_id); if (get_softmodem_params()->do_ra) ctxt.enb_flag = 0; LOG_W(RRC, "Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %lx, frame %d, subframe %d eNB_index %d \n", @@ -366,7 +378,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a ctxt.eNB_index); nr_pdcp_add_drbs(ctxt.enb_flag, - ctxt.rntiMaybeUEid, + cu_ue_id, 0, ue_context_p->ue_context.rb_config->drb_ToAddModList, (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, @@ -374,6 +386,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a kUPint, ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); + ctxt.rntiMaybeUEid = du_ue_id; // assume only a single bearer const NR_DRB_ToAddModList_t *drb_list = ue_context_p->ue_context.rb_config->drb_ToAddModList; DevAssert(drb_list->list.count == 1); From 5c42004e21e3e6041f1f1ca87b79778d2dedbaf6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 4 Jul 2023 14:46:10 +0200 Subject: [PATCH 36/47] RRC: switch to NGAP UE ID as CU UE ID --- openair2/E1AP/e1ap_api.c | 2 +- openair2/F1AP/f1ap_cu_ue_context_management.c | 4 +- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 2 +- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 2 +- openair2/RRC/NR/cucp_cuup_direct.c | 10 +- openair2/RRC/NR/nr_rrc_defs.h | 1 - openair2/RRC/NR/rrc_gNB.c | 92 ++++++++++++------- openair2/RRC/NR/rrc_gNB_GTPV1U.c | 6 +- openair2/RRC/NR/rrc_gNB_NGAP.c | 12 +-- openair2/RRC/NR/rrc_gNB_UE_context.c | 13 +-- openair2/RRC/NR/rrc_gNB_nsa.c | 15 +-- 11 files changed, 92 insertions(+), 67 deletions(-) diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index cf167f64e8..fc499c5b61 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -109,7 +109,7 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req, fill_DRB_configList_e1(&DRB_configList, pdu); } create_tunnel_req.num_tunnels = req->numPDUSessions; - create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF); + create_tunnel_req.ue_id = req->gNB_cu_cp_ue_id; // Create N3 tunnel int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req); diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index e742510d67..a72a359c5b 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -510,7 +510,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* 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(CUtype, instance)->gtpInst, - f1ap_ue_context_setup_req->gNB_DU_ue_id, + 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 @@ -1629,7 +1629,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, 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(CUtype, instance)->gtpInst, - f1ap_ue_context_modification_resp->gNB_DU_ue_id, + 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); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 6f6c2352a4..f62d8bcaa9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -686,7 +686,7 @@ static void deliver_pdu_drb_gnb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id req->buffer = gtpu_buffer_p; req->length = size; req->offset = GTPU_HEADER_OVERHEAD_MAX; - req->ue_id = ctxt.rntiMaybeUEid; + req->ue_id = ue_id; // use CU UE ID as GTP will use that to look up TEID req->bearer_id = rb_id; LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); extern instance_t CUuniqInstance; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index a22fe04b1b..53e2aca29e 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -476,7 +476,7 @@ rb_found: memcpy(req->buffer,buf,size); req->length=size; req->offset=0; - req->ue_id=ctx.rntiMaybeUEid; + req->ue_id=ue->rnti; // use RNTI here, which GTP will use to look up TEID req->bearer_id=rb_id; LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size); extern instance_t DUuniqInstance; diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 9c4e6462a4..6bef2d5e87 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -61,7 +61,7 @@ void fill_e1ap_bearer_setup_resp(e1ap_bearer_setup_resp_t *resp, drbSetup->numUpParam = 1; drbSetup->UpParamList[0].tlAddress = my_addr; drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst, - (ue_id & 0xFFFF), + ue_id, drb2Setup->id, drb2Setup->id, 0xFFFF, // We will set the right value from DU answer @@ -117,7 +117,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid; } create_tunnel_req.num_tunnels = UE->nb_of_pdusessions; - create_tunnel_req.ue_id = UE->rnti; + create_tunnel_req.ue_id = UE->rrc_ue_id; int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3, &create_tunnel_req, &create_tunnel_resp, @@ -150,7 +150,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, LOG_D(NR_RRC, "Configuring PDCP DRBs for UE %x\n", UE->rnti); nr_pdcp_add_drbs(ctxt_p->enb_flag, - ctxt_p->rntiMaybeUEid, + UE->rrc_ue_id, 0, DRB_configList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, @@ -166,7 +166,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0, 0); e1ap_bearer_setup_resp_t resp = {0}; resp.numPDUSessions = req->numPDUSessions; @@ -198,7 +198,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; // GTP tunnel for DL - fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rnti, remote_port, my_addr); + fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rrc_ue_id, remote_port, my_addr); } // actually, we should receive the corresponding context setup response // message at the RRC and always react to this one. So in the following, we diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 560d7a2a9c..36d9ae1b53 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -271,7 +271,6 @@ typedef struct gNB_RRC_UE_s { e_NR_IntegrityProtAlgorithm integrity_algorithm; NR_UE_STATE_t StatusRrc; - uint32_t cu_ue_id; rnti_t rnti; uint64_t random_ue_identity; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 5c8700ce41..1e2e82f74c 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -246,10 +246,10 @@ static void rrc_deliver_dl_rrc_message(void *deliver_pdu_data, ue_id_t ue_id, in void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size) { DevAssert(size > 0); - f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->cu_ue_id); - f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->cu_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .srb_id = srb_id}; + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .srb_id = srb_id}; deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; - nr_pdcp_data_req_srb(ue_p->cu_ue_id, srb_id, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); + nr_pdcp_data_req_srb(ue_p->rrc_ue_id, srb_id, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); } ///---------------------------------------------------------------------------------------------------------------/// @@ -491,12 +491,12 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, (char *)buf, size, "[MSG] RRC Setup\n"); - nr_pdcp_add_srbs(true, rnti, SRBs, 0, NULL, NULL); + nr_pdcp_add_srbs(true, ue_p->rrc_ue_id, SRBs, 0, NULL, NULL); freeSRBlist(SRBs); - f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rnti); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1ap_dl_rrc_message_t dl_rrc = { - .gNB_CU_ue_id = ue_p->cu_ue_id, + .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .rrc_container = buf, .rrc_container_length = size, @@ -552,12 +552,12 @@ static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t m LOG_I(NR_RRC, " [RAPROC] rnti: %04x Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", rnti, size); // configure MAC protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, ue_p->rrc_ue_id, 0, 0); apply_macrlc_config(rrc_instance_p, ue_context_pP, &ctxt); - f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rnti); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1ap_dl_rrc_message_t dl_rrc = { - .gNB_CU_ue_id = ue_p->cu_ue_id, + .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .rrc_container = buf, .rrc_container_length = size, @@ -585,9 +585,9 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context "[MSG] RRCReject \n"); LOG_I(NR_RRC, " [RAPROC] ue %04x Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", ue_p->rnti, size); - f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rnti); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1ap_dl_rrc_message_t dl_rrc = { - .gNB_CU_ue_id = ue_p->cu_ue_id, + .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .rrc_container = buf, .rrc_container_length = size, @@ -610,6 +610,7 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p ue_context_pP->ue_context.Srb[1].Active = 1; ue_context_pP->ue_context.Srb[2].Active = 0; ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED; + AssertFatal(ctxt_pP->rntiMaybeUEid == ue_context_pP->ue_context.rrc_ue_id, "logic bug: inconsistent IDs, must use CU UE ID!\n"); if (get_softmodem_params()->sa) { rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete); @@ -1096,14 +1097,14 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); nr_pdcp_add_srbs(ctxt_pP->enb_flag, - ctxt_pP->rntiMaybeUEid, + ue_p->rrc_ue_id, SRBs, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, kRRCenc, kRRCint); freeSRBlist(SRBs); nr_pdcp_add_drbs(ctxt_pP->enb_flag, - ctxt_pP->rntiMaybeUEid, + ue_p->rrc_ue_id, reestablish_ue_id, DRB_configList, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, @@ -1224,7 +1225,7 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint); /* Configure SRB1 for UE */ - nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, SRBs, 0, NULL, NULL); + nr_pdcp_add_srbs(ctxt_pP->enb_flag, ue_p->rrc_ue_id, SRBs, 0, NULL, NULL); LOG_D(NR_RRC, "UE %04x --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", ue_p->rnti); freeSRBlist(SRBs); LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_p->ciphering_algorithm, ue_p->integrity_algorithm); @@ -1525,6 +1526,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", rnti); rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti); + /* TODO this check is wrong, on different DUs there can be the same RNTI, this should not matter for us */ if (ue_context_p != NULL) { LOG_W(NR_RRC, "Got RRC setup request for a already registered RNTI %x, dropping the old one and give up this rrcSetupRequest\n", ue_context_p->ue_context.rnti); rrc_gNB_remove_ue_context(gnb_rrc_inst, ue_context_p); @@ -1604,7 +1606,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r UE->Srb[1].Active = 1; rrc_gNB_generate_RRCSetup(module_id, rnti, - rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti), + ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); } @@ -2002,9 +2004,9 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ } gNB_RRC_INST *rrc = RC.nrrrc[0]; - f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rnti); + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); f1ap_ue_context_modif_req_t ue_context_modif_req = { - .gNB_CU_ue_id = UE->cu_ue_id, + .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .mcc = rrc->configuration.mcc[0], .mnc = rrc->configuration.mnc[0], @@ -2024,6 +2026,13 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, { gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; + /* we look up by CU UE ID! Do NOT change back to RNTI! */ + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid); + if (!ue_context_p) { + LOG_E(RRC, "could not find UE context for CU UE ID %lu, aborting transaction\n", ctxt_pP->rntiMaybeUEid); + return -1; + } + if ((Srb_id != 1) && (Srb_id != 2)) { LOG_E(NR_RRC, "Received message on SRB%ld, should not have ...\n", Srb_id); } else { @@ -2051,8 +2060,6 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); } - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid); - if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) { switch (ul_dcch_msg->message.choice.c1->present) { case NR_UL_DCCH_MessageType__c1_PR_NOTHING: @@ -2286,7 +2293,11 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance { f1ap_ue_context_setup_t *resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->gNB_CU_ue_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_CU_ue_id); + if (!ue_context_p) { + LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", resp->gNB_CU_ue_id); + return; + } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; NR_CellGroupConfig_t *cellGroupConfig = NULL; @@ -2315,7 +2326,11 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p) const int instance = 0; f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->gNB_CU_ue_id); //here + 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); + return; + } /* TODO: marshall types correctly */ LOG_I(NR_RRC, "received UE Context Release Request for UE %u, forwarding to AMF\n", req->gNB_CU_ue_id); @@ -2330,13 +2345,17 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) const int instance = 0; f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, complete->gNB_CU_ue_id); // here + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, complete->gNB_CU_ue_id); + if (!ue_context_p) { + LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", complete->gNB_CU_ue_id); + return; + } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - nr_pdcp_remove_UE(UE->rnti); - newGtpuDeleteAllTunnels(instance, UE->rnti); + nr_pdcp_remove_UE(UE->rrc_ue_id); + newGtpuDeleteAllTunnels(instance, UE->rrc_ue_id); rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->rrc_ue_id); - LOG_I(NR_RRC, "removed UE %04x \n", UE->rnti); + LOG_I(NR_RRC, "removed UE CU UE ID %u/RNTI %04x \n", UE->rrc_ue_id, UE->rnti); rrc_gNB_remove_ue_context(rrc, ue_context_p); } @@ -2345,7 +2364,11 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->gNB_CU_ue_id, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->gNB_CU_ue_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_CU_ue_id); + if (!ue_context_p) { + LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", resp->gNB_CU_ue_id); + return; + } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (resp->drbs_to_be_setup_length > 0) { @@ -2601,9 +2624,9 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex srbs[0].lcid = 2; } - f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rnti); + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); f1ap_ue_context_modif_req_t ue_context_modif_req = { - .gNB_CU_ue_id = UE->cu_ue_id, + .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .mcc = rrc->configuration.mcc[0], .mnc = rrc->configuration.mnc[0], @@ -2622,9 +2645,9 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp // Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], resp->gNB_cu_cp_ue_id); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + AssertFatal(ue_context_p != NULL, "did not find UE with CU UE ID %d\n", resp->gNB_cu_cp_ue_id); protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, resp->gNB_cu_cp_ue_id, 0, 0, 0); gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; create_tunnel_resp.num_tunnels = resp->numPDUSessions; @@ -2764,7 +2787,6 @@ void *rrc_gnb_task(void *args_p) { instance, &ctxt, F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length); - DevAssert(F1AP_UL_RRC_MESSAGE(msg_p).gNB_CU_ue_id == F1AP_UL_RRC_MESSAGE(msg_p).gNB_DU_ue_id); rrc_gNB_decode_dcch(&ctxt, F1AP_UL_RRC_MESSAGE(msg_p).srb_id, F1AP_UL_RRC_MESSAGE(msg_p).rrc_container, @@ -2903,9 +2925,9 @@ rrc_gNB_generate_SecurityModeCommand( AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); /* the callback will fill the UE context setup request and forward it */ - f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rnti); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1ap_ue_context_setup_t ue_context_setup_req = { - .gNB_CU_ue_id = ue_p->cu_ue_id, + .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .mcc = rrc->configuration.mcc[0], .mnc = rrc->configuration.mnc[0], @@ -2981,9 +3003,9 @@ rrc_gNB_generate_RRCRelease( gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; const gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; - f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rnti); + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); f1ap_ue_context_release_cmd_t ue_context_release_cmd = { - .gNB_CU_ue_id = UE->cu_ue_id, + .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .cause = F1AP_CAUSE_RADIO_NETWORK, .cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c index e7bbe5835e..3ef3e62d51 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.c +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c @@ -52,7 +52,8 @@ int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_ } LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); + /* we look up by CU UE ID! Do NOT change back to RNTI! */ + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); if (!ue_context_p) { LOG_E(NR_RRC, "UE table error\n"); return -1; @@ -83,7 +84,8 @@ int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ct } LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); + /* we look up by CU UE ID! Do NOT change back to RNTI! */ + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); if (!ue_context_p) { LOG_E(NR_RRC, "UE table error\n"); return -1; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 0d0df4ec63..3e3fcf2e70 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -371,7 +371,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); return (-1); } - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); UE->amf_ue_ngap_id = req->amf_ue_ngap_id; uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions; if (nb_pdusessions_tosetup) { @@ -392,7 +392,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t memcpy(create_tunnel_req.dst_addr[i].buffer, req->pdusession_param[i].upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[i].buffer)); LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", i, create_tunnel_req.outgoing_teid[i], create_tunnel_req.pdusession_id[i]); } - create_tunnel_req.ue_id = UE->rnti; + create_tunnel_req.ue_id = UE->rrc_ue_id; gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp = {0}; int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req); if (ret != 0) { @@ -608,7 +608,7 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); /* Create message for PDCP (DLInformationTransfer_t) */ length = do_NR_DLInformationTransfer(instance, &buffer, rrc_gNB_get_next_transaction_identifier(instance), req->nas_pdu.length, req->nas_pdu.buffer); @@ -926,7 +926,7 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins return (-1); } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); ctxt.eNB_index = 0; bool all_failed = true; for (int i = 0; i < req->nb_pdusessions_tomodify; i++) { @@ -1153,7 +1153,7 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_ } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); ctxt.eNB_index = 0; rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); return 0; @@ -1265,7 +1265,7 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); LOG_I( NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu rrc_ue_id %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease); bool found = false; diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 92c81a94bb..aabcbbf44d 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -122,7 +122,7 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST *rrc_instance_pP, rrc_gNB_ue_context RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.rrc_ue_id - 1); - cu_remove_f1_ue_data(ue_context_pP->ue_context.cu_ue_id); + cu_remove_f1_ue_data(ue_context_pP->ue_context.rrc_ue_id); rrc_gNB_free_mem_ue_context(ue_context_pP); LOG_I(NR_RRC, "Removed UE context\n"); } @@ -175,6 +175,8 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, { rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc_instance_pP, rnti); + /* TODO: this should not matter, we can have multiple UEs at different DUs + * with the same RNTI! */ if (ue_context_p) { LOG_E(NR_RRC, "Cannot create new UE context, already exist rnti: %04x\n", rnti); return ue_context_p; @@ -185,19 +187,18 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, return NULL; gNB_RRC_UE_t *ue = &ue_context_p->ue_context; - ue->cu_ue_id = rnti; ue->rnti = rnti; ue->random_ue_identity = ue_identityP; f1_ue_data_t ue_data = {.secondary_ue = du_ue_id}; - AssertFatal(!cu_exists_f1_ue_data(ue->cu_ue_id), + AssertFatal(!cu_exists_f1_ue_data(ue->rrc_ue_id), "UE F1 Context for ID %d already exists, logic bug\n", - ue->cu_ue_id); - cu_add_f1_ue_data(ue->cu_ue_id, &ue_data); + ue->rrc_ue_id); + cu_add_f1_ue_data(ue->rrc_ue_id, &ue_data); RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p); LOG_I(NR_RRC, "Created new UE context: CU UE ID %u DU UE ID %u (rnti: %04x, random ue id %lx)\n", - ue->cu_ue_id, + ue->rrc_ue_id, du_ue_id, ue->rnti, ue->random_ue_identity); diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 1cceb3ec1f..1ab6530222 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -288,7 +288,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a create_tunnel_req.sgw_S1u_teid[i]); } - create_tunnel_req.rnti = ue_context_p->ue_context.rnti; + create_tunnel_req.rnti = ue_context_p->ue_context.rrc_ue_id; create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded; RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id); @@ -347,12 +347,13 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a // layers use different IDs (MAC/RLC use RNTI as DU UE ID, above use NGAP ID // as CU UE ID. uint32_t du_ue_id = ue_context_p->ue_context.rnti; - uint32_t cu_ue_id = ue_context_p->ue_context.rnti; - f1_ue_data_t du_ue_data = {.secondary_ue = cu_ue_id}; + static uint32_t rrc_ue_id = 0; + rrc_ue_id++; + f1_ue_data_t du_ue_data = {.secondary_ue = rrc_ue_id}; du_add_f1_ue_data(du_ue_id, &du_ue_data); f1_ue_data_t cu_ue_data = {.secondary_ue = du_ue_id}; - cu_add_f1_ue_data(cu_ue_id, &cu_ue_data); - LOG_I(RRC, "Assign CU UE ID %d and DU UE ID %d to UE RNTI %04x\n", cu_ue_id, du_ue_id, ue_context_p->ue_context.rnti); + cu_add_f1_ue_data(rrc_ue_id, &cu_ue_data); + LOG_I(RRC, "Assign CU UE ID %d and DU UE ID %d to UE RNTI %04x\n", rrc_ue_id, du_ue_id, ue_context_p->ue_context.rnti); // configure MAC and RLC bool ret = false; @@ -366,7 +367,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a } AssertFatal(ret, "cannot add NSA UE in MAC, aborting\n"); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, cu_ue_id, 0, 0, rrc->module_id); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rrc_ue_id, 0, 0, rrc->module_id); if (get_softmodem_params()->do_ra) ctxt.enb_flag = 0; LOG_W(RRC, "Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %lx, frame %d, subframe %d eNB_index %d \n", @@ -378,7 +379,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a ctxt.eNB_index); nr_pdcp_add_drbs(ctxt.enb_flag, - cu_ue_id, + rrc_ue_id, 0, ue_context_p->ue_context.rb_config->drb_ToAddModList, (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, From 763a95b12b53c470585db312b9698398c9089f0e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 6 Jul 2023 16:43:04 +0200 Subject: [PATCH 37/47] CU-UP/E1: mirror CU-CP UE ID in CU-UP, clean up messages - Use the same CU-UP in E1 as in CU-CP: we don't have a separate entity to allocate IDs, and we just use the same as the CU-CP - Correct gNB CU-UP/CP UE IDs in E1AP message types to 32bit - Set CU UP UE ID explicitly for clarity - Remove RNTI from E1 messages, E1 does not know what an RNTI is --- openair2/COMMON/e1ap_messages_types.h | 5 ++--- openair2/E1AP/e1ap.c | 2 +- openair2/E1AP/e1ap_api.c | 7 +++++++ openair2/RRC/NR/cucp_cuup_direct.c | 4 ++-- openair2/RRC/NR/rrc_gNB.c | 9 ++++++++- openair2/RRC/NR/rrc_gNB_NGAP.c | 1 - 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 7a88344efc..7a1a8b2698 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -156,7 +156,6 @@ typedef struct pdu_session_to_setup_s { typedef struct e1ap_bearer_setup_req_s { uint32_t gNB_cu_cp_ue_id; uint32_t gNB_cu_up_ue_id; - rnti_t rnti; uint64_t cipheringAlgorithm; uint64_t integrityProtectionAlgorithm; char encryptionKey[128]; @@ -216,8 +215,8 @@ typedef struct pdu_session_setup_s { } pdu_session_setup_t; typedef struct e1ap_bearer_setup_resp_s { - uint64_t gNB_cu_cp_ue_id; - uint64_t gNB_cu_up_ue_id; + uint32_t gNB_cu_cp_ue_id; + uint32_t gNB_cu_up_ue_id; int numDRBs; drb_setup_t DRBList[E1AP_MAX_NUM_DRBS]; int numPDUSessions; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 6c33ddf973..27eb9f5848 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1095,7 +1095,7 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_setup_req_t *setupReq, ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; ieC2->criticality = E1AP_Criticality_reject; ieC2->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; - ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id; + ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_up_ue_id; /* optional */ /* */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3); diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index fc499c5b61..9cec6b69f3 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -30,6 +30,7 @@ #include "openair2/RRC/LTE/MESSAGES/asn1_msg.h" #include "openair3/SECU/key_nas_deriver.h" #include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair2/F1AP/f1ap_ids.h" #include "e1ap_asnc.h" #include "e1ap_common.h" #include "e1ap.h" @@ -136,6 +137,11 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ AssertFatal(inst, ""); gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0}; + uint32_t gNB_cu_up_ue_id = req ->gNB_cu_cp_ue_id; + LOG_I(E1AP, "adding UE with CU-CP UE ID %d and CU-UP UE ID %d\n", req->gNB_cu_cp_ue_id, gNB_cu_up_ue_id); + f1_ue_data_t ue_data = {.secondary_ue = req->gNB_cu_cp_ue_id}; + cu_add_f1_ue_data(gNB_cu_up_ue_id, &ue_data); + // GTP tunnel for UL drb_config_N3gtpu_create(req, &create_tunnel_resp_N3, inst->gtpInstN3); @@ -148,6 +154,7 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->setupReq.remotePortF1U, my_addr); resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id; + resp->gNB_cu_up_ue_id = gNB_cu_up_ue_id; resp->numPDUSessions = req->numPDUSessions; for (int i=0; i < req->numPDUSessions; i++) { pdu_session_setup_t *pduSetup = resp->pduSession + i; diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 6bef2d5e87..e0853402d2 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -163,7 +163,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_cu_cp_ue_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0, 0); @@ -212,7 +212,7 @@ static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const r if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) return; instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; - CU_update_UP_DL_tunnel(req, gtpInst, req->rnti); + CU_update_UP_DL_tunnel(req, gtpInst, req->gNB_cu_cp_ue_id); } void cucp_cuup_message_transfer_direct_init(gNB_RRC_INST *rrc) { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 1e2e82f74c..fb965dc44d 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2375,7 +2375,7 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i e1ap_bearer_setup_req_t req = {0}; req.numPDUSessionsMod = UE->nb_of_pdusessions; req.gNB_cu_cp_ue_id = UE->rrc_ue_id; - req.rnti = UE->rnti; + req.gNB_cu_up_ue_id = UE->rrc_ue_id; for (int i = 0; i < req.numPDUSessionsMod; i++) { req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; for (int j = 0; j < resp->drbs_to_be_setup_length; j++) { @@ -2649,6 +2649,13 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, resp->gNB_cu_cp_ue_id, 0, 0, 0); + // currently: we don't have "infrastructure" to save the CU-UP UE ID, so we + // assume (and below check) that CU-UP UE ID == CU-CP UE ID + AssertFatal(resp->gNB_cu_cp_ue_id == resp->gNB_cu_up_ue_id, + "cannot handle CU-UP UE ID different from CU-CP UE ID (%d vs %d)\n", + resp->gNB_cu_cp_ue_id, + resp->gNB_cu_up_ue_id); + gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; create_tunnel_resp.num_tunnels = resp->numPDUSessions; for (int i=0; i < resp->numPDUSessions; i++) { diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 3e3fcf2e70..8a9a08abd7 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -760,7 +760,6 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer; decodePDUSessionResourceSetup(session); bearer_req.gNB_cu_cp_ue_id = msg->gNB_ue_ngap_id; - bearer_req.rnti = UE->rnti; bearer_req.cipheringAlgorithm = UE->ciphering_algorithm; bearer_req.integrityProtectionAlgorithm = UE->integrity_algorithm; nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, (uint8_t *)bearer_req.encryptionKey); From 9790246daf7c6a22ac3a1933113827d0a4823ccf Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 7 Jul 2023 16:01:14 +0200 Subject: [PATCH 38/47] Do-ra: write out directly --- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 4 +++- openair2/RRC/NR/rrc_gNB_nsa.c | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index f62d8bcaa9..18f0944b09 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -633,7 +633,9 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, if (IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN) { LOG_D(PDCP, "IP packet received with size %d, to be sent to SDAP interface, UE ID/RNTI: %ld\n", size, ue->rntiMaybeUEid); - sdap_data_ind(entity->rb_id, entity->is_gnb, entity->has_sdap_rx, entity->pdusession_id, ue->rntiMaybeUEid, buf, size); + // in NoS1 mode: the SDAP should write() packets to an FD (TUN interface), + // so below, set is_gnb == 0 to do that + sdap_data_ind(entity->rb_id, 0, entity->has_sdap_rx, entity->pdusession_id, ue->rntiMaybeUEid, buf, size); } else{ for (i = 0; i < MAX_DRBS_PER_UE; i++) { diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 1ab6530222..c7cba3e8e8 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -368,7 +368,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a AssertFatal(ret, "cannot add NSA UE in MAC, aborting\n"); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rrc_ue_id, 0, 0, rrc->module_id); - if (get_softmodem_params()->do_ra) ctxt.enb_flag = 0; LOG_W(RRC, "Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %lx, frame %d, subframe %d eNB_index %d \n", &ctxt, From 644a5768a3acabcd20f3399b05d30cb32ac04a03 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 11 Jul 2023 12:13:33 +0200 Subject: [PATCH 39/47] nrRRC_stats.log: provide info about UE (IDs, RRC state, PDU sessions) --- openair2/RRC/NR/rrc_gNB.c | 53 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index fb965dc44d..d168ae6b4c 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2694,6 +2694,36 @@ static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults) } } +static const char *get_rrc_connection_status_text(NR_UE_STATE_t state) +{ + switch (state) { + case NR_RRC_INACTIVE: return "inactive"; + case NR_RRC_IDLE: return "idle"; + case NR_RRC_SI_RECEIVED: return "SI-received"; + case NR_RRC_CONNECTED: return "connected"; + case NR_RRC_RECONFIGURED: return "reconfigured"; + case NR_RRC_HO_EXECUTION: return "HO-execution"; + default: AssertFatal(false, "illegal RRC state %d\n", state); return "illegal"; + } + return "illegal"; +} + +static const char *get_pdusession_status_text(pdu_session_status_t status) +{ + switch (status) { + case PDU_SESSION_STATUS_NEW: return "new"; + case PDU_SESSION_STATUS_DONE: return "done"; + case PDU_SESSION_STATUS_ESTABLISHED: return "established"; + case PDU_SESSION_STATUS_REESTABLISHED: return "reestablished"; + case PDU_SESSION_STATUS_TOMODIFY: return "to-modify"; + case PDU_SESSION_STATUS_FAILED: return "failed"; + case PDU_SESSION_STATUS_TORELEASE: return "to-release"; + case PDU_SESSION_STATUS_RELEASED: return "released"; + default: AssertFatal(false, "illegal PDU status code %d\n", status); return "illegal"; + } + return "illegal"; +} + static void write_rrc_stats(const gNB_RRC_INST *rrc) { const char *filename = "nrRRC_stats.log"; @@ -2703,19 +2733,33 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) return; } + int i = 0; rrc_gNB_ue_context_t *ue_context_p = NULL; /* cast is necessary to eliminate warning "discards ‘const’ qualifier" */ RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &((gNB_RRC_INST *)rrc)->rrc_ue_head) { const gNB_RRC_UE_t *ue_ctxt = &ue_context_p->ue_context; - const rnti_t rnti = ue_ctxt->rnti; - - fprintf(f, "NR RRC UE rnti %04x:", rnti); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_ctxt->rrc_ue_id); + fprintf(f, + "UE %d CU UE ID %d DU UE ID %d RNTI %04x random identity %016lx", + i, + ue_ctxt->rrc_ue_id, + ue_data.secondary_ue, + ue_ctxt->rnti, + ue_ctxt->random_ue_identity); if (ue_ctxt->Initialue_identity_5g_s_TMSI.presence) fprintf(f, " S-TMSI %x", ue_ctxt->Initialue_identity_5g_s_TMSI.fiveg_tmsi); + fprintf(f, ":\n"); - fprintf(f, "\n"); + fprintf(f, " RRC status %s\n", get_rrc_connection_status_text(ue_ctxt->StatusRrc)); + + if (ue_ctxt->nb_of_pdusessions == 0) + fprintf(f, " (no PDU sessions)\n"); + for (int nb_pdu = 0; nb_pdu < ue_ctxt->nb_of_pdusessions; ++nb_pdu) { + const rrc_pdu_session_param_t *pdu = &ue_ctxt->pduSession[nb_pdu]; + fprintf(f, " PDU session %d ID %d status %s\n", nb_pdu, pdu->param.pdusession_id, get_pdusession_status_text(pdu->status)); + } if (ue_ctxt->UE_Capability_nr) { fprintf(f, @@ -2729,6 +2773,7 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) if (ue_ctxt->measResults) print_rrc_meas(f, ue_ctxt->measResults); + ++i; } fclose(f); From 1c07afbeb6f365097025116a65258498a7003b1f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 21 Jul 2023 16:17:46 +0200 Subject: [PATCH 40/47] RRC: Remove checks for UEs with existing RNTI The RRC gives its own RRC UE ID. It won't intervene if DUs assign the same RNTI to different UEs: it simply does not care what the DUs do with the RNTI. --- openair2/RRC/NR/rrc_gNB.c | 8 ++------ openair2/RRC/NR/rrc_gNB_UE_context.c | 11 +---------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d168ae6b4c..3137816510 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1525,13 +1525,9 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", rnti); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti); - /* TODO this check is wrong, on different DUs there can be the same RNTI, this should not matter for us */ - if (ue_context_p != NULL) { - LOG_W(NR_RRC, "Got RRC setup request for a already registered RNTI %x, dropping the old one and give up this rrcSetupRequest\n", ue_context_p->ue_context.rnti); - rrc_gNB_remove_ue_context(gnb_rrc_inst, ue_context_p); - } else { + { rrcSetupRequest = &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest; + rrc_gNB_ue_context_t *ue_context_p = NULL; if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { /* randomValue BIT STRING (SIZE (39)) */ if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index aabcbbf44d..e73375fb65 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -173,16 +173,7 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, uint32_t du_ue_id) //----------------------------------------------------------------------------- { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc_instance_pP, rnti); - - /* TODO: this should not matter, we can have multiple UEs at different DUs - * with the same RNTI! */ - if (ue_context_p) { - LOG_E(NR_RRC, "Cannot create new UE context, already exist rnti: %04x\n", rnti); - return ue_context_p; - } - - ue_context_p = rrc_gNB_allocate_new_ue_context(rrc_instance_pP); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc_instance_pP); if (ue_context_p == NULL) return NULL; From b90a59a67115e944d0f81035c32e89adc48347cb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 26 Jul 2023 18:52:16 +0200 Subject: [PATCH 41/47] Trigger Reestablishment via resetting RLC sequence numbers Plugin can trigger reestablishment (on DU) and show counters of reestablishment (on CU) --- .../xml_files/container_sa_b200_quectel.xml | 6 +-- .../container_sa_sc_b200_quectel.xml | 6 +-- common/utils/telnetsrv/telnetsrv_ci.c | 50 ++++++++++--------- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 18 +++++++ openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h | 3 ++ 5 files changed, 54 insertions(+), 29 deletions(-) diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml index 121b836769..0296ecfe93 100644 --- a/ci-scripts/xml_files/container_sa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml @@ -111,7 +111,7 @@ IdleSleep Sleep - 20 + 10 @@ -168,14 +168,14 @@ Custom_Command Trigger Reestablishment ofqot - echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'force-remove UE RNTI [0-9a-f]{4} from RLC to trigger reestablishment' + echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' yes Custom_Command Verify Reestablishment ofqot - echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1 reconf_after_reestab 1' + echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' yes diff --git a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml index 0d4dd8f27e..d603b3f1ea 100644 --- a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml @@ -105,7 +105,7 @@ IdleSleep Sleep - 20 + 10 @@ -162,14 +162,14 @@ Custom_Command Trigger Reestablishment ofqot - echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'force-remove UE RNTI [0-9a-f]{4} from RLC to trigger reestablishment' + echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' yes Custom_Command Verify Reestablishment ofqot - echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1 reconf_after_reestab 1' + echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' yes diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 3f4930d02b..2d7019b00e 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -28,15 +28,17 @@ #include #include "openair2/RRC/NR/rrc_gNB_UE_context.h" -#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h" #define TELNETSERVERCODE #include "telnetsrv.h" #define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return 1; } while (0) -static int get_single_ue_rnti(void) +static int get_single_ue_rnti_mac(void) { NR_UE_info_t *ue = NULL; UE_iterator(RC.nrmac[0]->UE_info.list, it) { @@ -48,11 +50,6 @@ static int get_single_ue_rnti(void) if (!ue) return -1; - // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti); - if (!rrcue) - return -1; - return ue->rnti; } @@ -61,7 +58,7 @@ int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt) if (buf) ERROR_MSG_RET("no parameter allowed\n"); - int rnti = get_single_ue_rnti(); + int rnti = get_single_ue_rnti_mac(); if (rnti < 1) ERROR_MSG_RET("different number of UEs\n"); @@ -71,23 +68,32 @@ int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt) int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) { + if (!RC.nrrrc) + ERROR_MSG_RET("no RRC present, cannot list counts\n"); + rrc_gNB_ue_context_t *ue = NULL; int rnti = -1; if (!buf) { - rnti = get_single_ue_rnti(); - if (rnti < 1) - ERROR_MSG_RET("no UE found\n"); + rrc_gNB_ue_context_t *l = NULL; + int n = 0; + RB_FOREACH(l, rrc_nr_ue_tree_s, &RC.nrrrc[0]->rrc_ue_head) { + if (ue == NULL) ue = l; + n++; + } + if (!ue) + ERROR_MSG_RET("could not find any UE in RRC\n"); + if (n > 1) + ERROR_MSG_RET("more than one UE in RRC present\n"); } else { rnti = strtol(buf, NULL, 16); if (rnti < 1 || rnti >= 0xfffe) ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); + ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); + if (!ue) + ERROR_MSG_RET("could not find UE with RNTI %04x in RRC\n"); } - rrc_gNB_ue_context_t *ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); - if (!ue) - ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); - prnt("UE RNTI %04x reestab %d reconf_after_reestab %d\n", - rnti, + ue->ue_context.rnti, ue->ue_context.ue_reestablishment_counter, ue->ue_context.ue_reconfiguration_after_reestablishment_counter); return 0; @@ -95,9 +101,11 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) { + if (!RC.nrmac) + ERROR_MSG_RET("no MAC/RLC present, cannot trigger reestablishment\n"); int rnti = -1; if (!buf) { - rnti = get_single_ue_rnti(); + rnti = get_single_ue_rnti_mac(); if (rnti < 1) ERROR_MSG_RET("no UE found\n"); } else { @@ -106,13 +114,9 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); } - // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); - if (!rrcue) - ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); + nr_rlc_test_trigger_reestablishment(rnti); - nr_rlc_remove_ue(rnti); - prnt("force-remove UE RNTI %04x from RLC to trigger reestablishment\n", rnti); + prnt("Reset RLC counters of UE RNTI %04x to trigger reestablishment\n", rnti); return 0; } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 53e2aca29e..b6f1065d6c 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -1010,6 +1010,24 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } +/* This function is for testing purposes. At least on a COTS UE, it will + * trigger a reestablishment. */ +void nr_rlc_test_trigger_reestablishment(int rnti) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + if (ue == NULL) { + nr_rlc_manager_unlock(nr_rlc_ue_manager); + LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", rnti); + return; + } + /* we simply assume the SRB exists, because the scheduler creates it as soon + * as the UE context is created. */ + nr_rlc_entity_t *ent = ue->srb[0]; + ent->reestablishment(ent); + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + void nr_rlc_tick(int frame, int subframe) { if (frame != nr_rlc_current_time_last_frame || diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 3b4bce7176..051b6ab078 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -44,6 +44,9 @@ void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Beare void nr_rlc_remove_ue(int rnti); +/* test function for CI to trigger reestablishments */ +void nr_rlc_test_trigger_reestablishment(int rnti); + int nr_rlc_get_available_tx_space( const rnti_t rntiP, const logical_chan_id_t channel_idP); From 04abbdb668ea615f9b2a2e59d64aed4abe6f5da5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 25 Jul 2023 15:36:02 +0200 Subject: [PATCH 42/47] Implement PDCP reset counters for reestablishment After a reestablishment, the PDCP sequence number counters have to be reset. Implement an API to allow the RRC to reset the sequence numbers for a particular UE in the case of reestablishment --- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 33 +++++++++++++++++++++++ openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h | 1 + openair2/RRC/NR/rrc_gNB.c | 1 + 3 files changed, 35 insertions(+) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 18f0944b09..3a740fd3b4 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -1071,6 +1071,39 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id, return 1; } +void nr_pdcp_reestablishment(ue_id_t ue_id) +{ + // TODO implement this on a per RB basis following TS 38.323 Sec 5.1.2 + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + if (ue == NULL) { + LOG_E(PDCP, "Cannot find PDCP entity for UE %lx\n", ue_id); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + return; + } + + for (int i = 0; i < 3; i++) { + nr_pdcp_entity_t *srb = ue->srb[i]; + if (srb != NULL) { + srb->tx_next = 0; + srb->rx_next = 0; + srb->rx_deliv = 0; + srb->rx_reord = 0; + } + } + + for (int i = 0; i < MAX_DRBS_PER_UE; i++) { + nr_pdcp_entity_t *drb = ue->drb[i]; + if (drb != NULL) { + // drb->tx_next = 0; // Should continue from the previous value + drb->rx_next = 0; + //drb->rx_deliv = 0; // should continue from the previous value + drb->rx_reord = 0; + } + } + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); +} + bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, const rb_id_t rb_id, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 64bb4ff3e6..92de7c8f5f 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -58,6 +58,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid); bool nr_pdcp_remove_UE(ue_id_t ue_id); +void nr_pdcp_reestablishment(ue_id_t ue_id); void nr_pdcp_config_set_security(ue_id_t ue_id, const rb_id_t rb_id, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3137816510..95f9e7e1ed 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1238,6 +1238,7 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, kRRCenc, kRRCint, kUPenc); + nr_pdcp_reestablishment(ctxt_pP->rntiMaybeUEid); if (!NODE_IS_CU(rrc->node_type)) { apply_macrlc_config_reest(rrc, ue_context_pP, ctxt_pP, ctxt_pP->rntiMaybeUEid); From 7a298e73cd7aa8fa82abde0d42834867c2f0cf73 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 7 Jul 2023 14:19:17 +0200 Subject: [PATCH 43/47] Repair reestablishment and make it work via F1 This commit repairs the reestablishment after the introduction of the CU UE ID in the CU, different from the DU UE ID. Now, the CU uses an identifier different from the RNTI, used in the MAC, to refer to UEs. To repair the reestablishment, a number of changes needed to be introduced: - Handle old_gNB_DU_UE_id in MAC The MAC handles the old_gNB_DU_UE_id field in the DL RRC Message. The commit adds encoding/decoding of the field. The MAC will drop the old UE, but retain the CellGroup of the corresponding UE(!). Because a UE releases the spCellGroup on reestablishment, the MAC does the same; it needs to reapply the old configuration after a reconfiguration. For the latter, introduce new variables to keep a "future" CellGroupConfig to be applied (reconfigCellGroup) and a flag (expect_reconfiguration) that applies the CellGroupConfig if a DL RRC Message transfer on DCCH, which is assumed to be the reconfiguration. - Add RNTI change in RLC The RLC needs to reuse the old UE context. Hence, we simply change the RNTI in the old context, and delete the new one. - No PDCP UE ID change The previous implementation of the PDCP used the RNTI; hence, the ID needed to be switch (as above for the RLC). Since the PDCP now also uses the CU UE ID, no identifier change is needed, and we remove all corresponding code. - No MAC modifications/update from CU As foreseen by the spec, the CU does not modify or change the cellGroupConfig in the RRC during reestablishment. This change will be generalized in the future to all of the RRC. Also, the nr_rrc_mac_remove_ue() function has been removed: the MAC handles any UE changes autonomeously, without being triggered from the RRC explicitly. - Remove reestablish_rnti_map The RRC does not use RNTIs for UE identification. Hence, a reestablish_rnti_map to link two UEs to each other is not necessary anymore. --- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 15 +- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 14 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 2 +- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 47 ++- openair2/LAYER2/NR_MAC_gNB/main.c | 2 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 4 + openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c | 2 +- openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h | 2 +- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 18 +- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h | 1 - openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 21 ++ openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h | 1 + openair2/RRC/NR/L2_nr_interface.c | 10 - openair2/RRC/NR/cucp_cuup_direct.c | 1 - openair2/RRC/NR/nr_rrc_defs.h | 10 - openair2/RRC/NR/nr_rrc_proto.h | 2 - openair2/RRC/NR/rrc_gNB.c | 284 ++++-------------- openair2/RRC/NR/rrc_gNB_UE_context.c | 10 - openair2/RRC/NR/rrc_gNB_UE_context.h | 1 - openair2/RRC/NR/rrc_gNB_nsa.c | 3 - openair2/RRC/NR_UE/rrc_UE.c | 1 - openair3/ocp-gtpu/gtp_itf.cpp | 20 +- openair3/ocp-gtpu/gtp_itf.h | 7 +- 23 files changed, 165 insertions(+), 313 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 12e0d96c14..13bc9954a3 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -146,13 +146,14 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, /* optional */ /* c3. oldgNB_DU_UE_F1AP_ID */ - /* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_NOTHING; - ie3->value.choice.oldgNB_DU_UE_F1AP_ID = f1ap_dl_rrc->old_gNB_DU_ue_id; - }*/ + if (f1ap_dl_rrc->old_gNB_DU_ue_id != NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID_1; + ie3->value.choice.GNB_DU_UE_F1AP_ID_1 = *f1ap_dl_rrc->old_gNB_DU_ue_id; + } + /* mandatory */ /* c4. SRBID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie4); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index dfe33ef1ab..bcb38029cd 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -50,6 +50,7 @@ #include "asn1_msg.h" #include "intertask_interface.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" @@ -76,9 +77,15 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, /* optional */ /* oldgNB_DU_UE_F1AP_ID */ - if (0) { - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, true); + uint32_t *old_gNB_DU_ue_id = NULL; + uint32_t old_gNB_DU_ue_id_stack = 0; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, false); + if (ie) { + /* strange: it is not named OLD_GNB_DU_UE... */ + old_gNB_DU_ue_id_stack = ie->value.choice.GNB_DU_UE_F1AP_ID_1; + old_gNB_DU_ue_id = &old_gNB_DU_ue_id_stack; + gtpv1u_update_ue_id(getCxt(false, instance)->gtpInst, old_gNB_DU_ue_id_stack, du_ue_f1ap_id); } /* mandatory */ @@ -126,6 +133,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, f1ap_dl_rrc_message_t dl_rrc = { .gNB_CU_ue_id = cu_ue_f1ap_id, .gNB_DU_ue_id = du_ue_f1ap_id, + .old_gNB_DU_ue_id = old_gNB_DU_ue_id, .rrc_container_length = ie->value.choice.RRCContainer.size, .rrc_container = ie->value.choice.RRCContainer.buf, .srb_id = srb_id diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 8899be18e6..3d980dd217 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -79,7 +79,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { // set up PDCP, RLC, MAC nr_pdcp_layer_init(); - nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, 0, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); + nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); nr_rlc_add_drb(nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); nr_ue_mac_inst->logicalChannelBearer_exist[0] = true; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index ee66931475..0a450a1198 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -295,7 +295,52 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) du_add_f1_ue_data(dl_rrc->gNB_DU_ue_id, &new_ue_data); } - AssertFatal(dl_rrc->old_gNB_DU_ue_id == NULL, "changing RNTI not implemented yet\n"); + if (UE->expect_reconfiguration && dl_rrc->srb_id == DCCH) { + /* we expected a reconfiguration, and this is on DCCH. We assume this is + * the reconfiguration; nr_mac_update_cellgroup() brings the config into + * the form expected by nr_mac_update_timers(), and we set the timer to + * apply the real configuration at expiration. + * Calling it nr_mac_update_cellgroup() is misleading, and using an + * intermediate buffer seems not necessary. This is for historical reasons, + * when we only had pointer to an RRC structure, and wanted to duplicate + * the contents to be applied later. The actually interesting function here + * is also configure_UE_BWP(), only called in nr_mac_update_timers(). + * TODO: This should be cleaned up when the whole CellGroupConfig is + * handled entirely at the DU: no intermediate buffer, trigger the timer + * from a function (there is nr_mac_enable_ue_rrc_processing_timer(), which + * is called from the RRC, hence locks the scheduler, which we cannot use). */ + LOG_I(NR_MAC, "triggering rrc_processing_timer time UE %04x\n", UE->rnti); + pthread_mutex_lock(&mac->sched_lock); + nr_mac_update_cellgroup(mac, dl_rrc->gNB_DU_ue_id, UE->reconfigCellGroup); + pthread_mutex_unlock(&mac->sched_lock); + const uint16_t sl_ahead = mac->if_inst->sl_ahead; + NR_SubcarrierSpacing_t scs = 1; + int delay = 10; + UE->UE_sched_ctrl.rrc_processing_timer = (delay << scs) + sl_ahead; + } + + if (dl_rrc->old_gNB_DU_ue_id != NULL) { + AssertFatal(*dl_rrc->old_gNB_DU_ue_id != dl_rrc->gNB_DU_ue_id, + "logic bug: current and old gNB DU UE ID cannot be the same\n"); + /* 38.401 says: "Find UE context based on old gNB-DU UE F1AP ID, replace + * old C-RNTI/PCI with new C-RNTI/PCI". So we delete the new contexts + * below, then change the C-RNTI of the old one to the new one */ + NR_UE_info_t *oldUE = find_nr_UE(&mac->UE_info, *dl_rrc->old_gNB_DU_ue_id); + DevAssert(oldUE); + pthread_mutex_lock(&mac->sched_lock); + /* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it + * from the current configuration. Also, expect the reconfiguration from + * the CU, so save the old UE's CellGroup for the new UE */ + UE->CellGroup->spCellConfig = NULL; + nr_mac_update_cellgroup(mac, dl_rrc->gNB_DU_ue_id, UE->CellGroup); + UE->reconfigCellGroup = oldUE->CellGroup; + UE->expect_reconfiguration = true; + oldUE->CellGroup = NULL; + mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id); + pthread_mutex_unlock(&mac->sched_lock); + nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); + nr_rlc_update_rnti(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); + } /* the DU ue id is the RNTI */ nr_rlc_srb_recv_sdu(dl_rrc->gNB_DU_ue_id, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index ed16ffd1d7..7fd559fdcd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -284,7 +284,7 @@ void mac_top_init_gNB(ngran_node_t node_type) * will output the packets at a local interface, which is in line with * the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */ // setup PDCP, RLC - nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, 0, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); + nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); // free memory diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index b774ab6c72..457497679a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -675,7 +675,11 @@ typedef struct { NR_UE_DL_BWP_t current_DL_BWP; NR_UE_UL_BWP_t current_UL_BWP; NR_mac_stats_t mac_stats; + /// currently active CellGroupConfig NR_CellGroupConfig_t *CellGroup; + /// CellGroupConfig that is to be activated after the next reconfiguration + NR_CellGroupConfig_t *reconfigCellGroup; + bool expect_reconfiguration; char cg_buf[32768]; /* arbitrary size */ asn_enc_rval_t enc_rval; // UE selected beam index diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c index d56c22f609..97370c5964 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c @@ -32,7 +32,7 @@ void e1_add_drb(int is_gnb, unsigned char *ciphering_key, unsigned char *integrity_key) { - add_drb_am(is_gnb, ue_id, 0, s, ciphering_algorithm, integrity_algorithm, + add_drb_am(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h index f45f3f0458..3c16996126 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h @@ -45,7 +45,7 @@ void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag, uint8_t *const kUPenc, uint8_t *const kUPint); -void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, +void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 3a740fd3b4..be22753026 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -788,7 +788,7 @@ static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) +void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -875,14 +875,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st has_integrity ? integrity_key : NULL); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); - if (reestablish_ue_id > 0) { - nr_pdcp_ue_t *reestablish_ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, reestablish_ue_id); - if (reestablish_ue != NULL) { - pdcp_drb->tx_next = reestablish_ue->drb[drb_id - 1]->tx_next; - LOG_I(PDCP, "Applying tx_next %d in DRB %d from old UEid %lx to new UEid %lx\n", reestablish_ue->drb[drb_id - 1]->tx_next, drb_id, reestablish_ue_id, rntiMaybeUEid); - } - } - LOG_D(PDCP, "%s:%d:%s: added drb %d to UE ID/RNTI %ld\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rntiMaybeUEid); new_nr_sdap_entity(is_gnb, has_sdap_rx, has_sdap_tx, rntiMaybeUEid, pdusession_id, is_sdap_DefaultDRB, drb_id, mappedQFIs2Add, mappedQFIs2AddCount); @@ -892,7 +884,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st static void add_drb(int is_gnb, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config, int ciphering_algorithm, @@ -902,12 +893,12 @@ static void add_drb(int is_gnb, { switch (rlc_Config->present) { case NR_RLC_Config_PR_am: - add_drb_am(is_gnb, rntiMaybeUEid, reestablish_ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); + add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); break; case NR_RLC_Config_PR_um_Bi_Directional: // add_drb_um(rntiMaybeUEid, s); /* hack */ - add_drb_am(is_gnb, rntiMaybeUEid, reestablish_ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); + add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); break; default: LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", @@ -929,7 +920,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, @@ -938,7 +928,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, { if (drb2add_list != NULL) { for (int i = 0; i < drb2add_list->list.count; i++) { - add_drb(enb_flag, rntiMaybeUEid, reestablish_ue_id, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint); + add_drb(enb_flag, rntiMaybeUEid, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint); } } else LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 92de7c8f5f..f00ab98422 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -48,7 +48,6 @@ bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index b6f1065d6c..7d17829e4f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -1010,6 +1010,27 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } +bool nr_rlc_update_rnti(int from_rnti, int to_rnti) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, from_rnti); + if (ue == NULL) { + nr_rlc_manager_unlock(nr_rlc_ue_manager); + LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", from_rnti); + return false; + } + ue->rnti = to_rnti; + LOG_I(RLC, "Update old UE RNTI %04x context to RNTI %04x\n", from_rnti, to_rnti); + for (int i = 0; i < sizeof(ue->srb) / sizeof(ue->srb[0]); ++i) + if (ue->srb[i]) + ue->srb[i]->reestablishment(ue->srb[i]); + for (int i = 0; i < sizeof(ue->drb) / sizeof(ue->drb[0]); ++i) + if (ue->drb[i]) + ue->drb[i]->reestablishment(ue->drb[i]); + nr_rlc_manager_unlock(nr_rlc_ue_manager); + return true; +} + /* This function is for testing purposes. At least on a COTS UE, it will * trigger a reestablishment. */ void nr_rlc_test_trigger_reestablishment(int rnti) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 051b6ab078..15fe286435 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -43,6 +43,7 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); void nr_rlc_remove_ue(int rnti); +bool nr_rlc_update_rnti(int from_rnti, int to_rnti); /* test function for CI to trigger reestablishments */ void nr_rlc_test_trigger_reestablishment(int rnti); diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 0f524a0241..3334842616 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -52,16 +52,6 @@ extern RAN_CONTEXT_t RC; -void nr_rrc_mac_remove_ue(rnti_t rntiMaybeUEid) -{ - nr_rlc_remove_ue(rntiMaybeUEid); - - gNB_MAC_INST *nrmac = RC.nrmac[0]; - NR_SCHED_LOCK(&nrmac->sched_lock); - mac_remove_nr_ue(nrmac, rntiMaybeUEid); - NR_SCHED_UNLOCK(&nrmac->sched_lock); -} - void nr_rrc_mac_update_cellgroup(rnti_t rntiMaybeUEid, NR_CellGroupConfig_t *cgc) { gNB_MAC_INST *nrmac = RC.nrmac[0]; diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index e0853402d2..9dccef4286 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -151,7 +151,6 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, LOG_D(NR_RRC, "Configuring PDCP DRBs for UE %x\n", UE->rnti); nr_pdcp_add_drbs(ctxt_p->enb_flag, UE->rrc_ue_id, - 0, DRB_configList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kUPenc, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 36d9ae1b53..e05202e553 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -255,9 +255,6 @@ typedef struct gNB_RRC_UE_s { NR_RRCReconfiguration_t *reconfig; NR_RadioBearerConfig_t *rb_config; - /* Pointer to save spCellConfig during RRC Reestablishment procedures */ - NR_SpCellConfig_t *spCellConfigReestablishment; - ImsiMobileIdentity_t imsi; /* KgNB as derived from KASME received from EPC */ @@ -378,11 +375,6 @@ typedef struct cucp_cuup_if_s { cucp_cuup_bearer_context_setup_func_t bearer_context_mod; } cucp_cuup_if_t; -typedef struct nr_reestablish_rnti_map_s { - ue_id_t ue_id; - rnti_t c_rnti; -} nr_reestablish_rnti_map_t; - //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -430,8 +422,6 @@ typedef struct gNB_RRC_INST_s { // security configuration (preferred algorithms) nr_security_configuration_t security; - nr_reestablish_rnti_map_t nr_reestablish_rnti_map[MAX_MOBILES_PER_GNB]; - nr_mac_rrc_dl_if_t mac_rrc; cucp_cuup_if_t cucp_cuup; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 73cfb33c9d..7502662da3 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -119,7 +119,6 @@ void *rrc_gnb_task(void *args_p); \ *reOffset Pointer to RE Offset Value */ void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, long *ptrsNrb, long *ptrsMcs, long *epre_Ratio, long *reOffset); -void nr_rrc_mac_remove_ue(rnti_t rntiP); void nr_rrc_mac_update_cellgroup(rnti_t rntiMaybeUEid, NR_CellGroupConfig_t *cgc); int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, @@ -164,7 +163,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 95f9e7e1ed..1696671949 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -458,14 +458,6 @@ static void apply_macrlc_config(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const u freeDRBlist(DRBs); } -void apply_macrlc_config_reest(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP, ue_id_t ue_id) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - nr_rrc_mac_update_cellgroup(ue_id, ue_p->masterCellGroup); - - nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, ue_p->Srb, maxSRBs, ue_p->masterCellGroup->rlc_BearerToAddModList); -} - //----------------------------------------------------------------------------- static void rrc_gNB_generate_RRCSetup(instance_t instance, rnti_t rnti, @@ -513,7 +505,7 @@ static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t m rrc_gNB_ue_context_t *ue_context_pP = NULL; gNB_RRC_INST *rrc_instance_p = RC.nrrrc[module_id]; - AssertFatal(!NODE_IS_CU(rrc_instance_p->node_type), "Not functional in F1-split: no DU UE ID available\n"); + AssertFatal(false, "this is not implemented\n"); /* for creating a UE context, we need the DU ID to be able to indicate the * DU. This is not yet implemented for Reestablishment. We know that in * monolithic, the DU UE ID is the RNTI, so use that for the moment */ @@ -1077,25 +1069,9 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co /* Refresh SRBs/DRBs */ LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti); - ue_id_t reestablish_ue_id = 0; - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i]; - if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { - ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++; - reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti; - LOG_D(NR_RRC, - "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", - i, - nr_reestablish_rnti_map->ue_id, - nr_reestablish_rnti_map->c_rnti); - // clear current C-RNTI from map - nr_reestablish_rnti_map->ue_id = 0; - nr_reestablish_rnti_map->c_rnti = 0; - break; - } - } - NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); + ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++; + NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); nr_pdcp_add_srbs(ctxt_pP->enb_flag, ue_p->rrc_ue_id, SRBs, @@ -1105,7 +1081,6 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co freeSRBlist(SRBs); nr_pdcp_add_drbs(ctxt_pP->enb_flag, ue_p->rrc_ue_id, - reestablish_ue_id, DRB_configList, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, kUPenc, @@ -1176,11 +1151,11 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co } //----------------------------------------------------------------------------- -void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - const int CC_id) +static void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t *masterCellGroup_from_DU, + NR_ServingCellConfigCommon_t *scc, + const rnti_t old_rnti) //----------------------------------------------------------------------------- { // int UE_id = -1; @@ -1192,18 +1167,13 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, int enable_ciphering = 0; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - // Need to drop spCellConfig when there is a RRCReestablishment - // Save spCellConfig in spCellConfigReestablishment to recover after Reestablishment is completed - ue_p->spCellConfigReestablishment = ue_p->masterCellGroup->spCellConfig; - ue_p->masterCellGroup->spCellConfig = NULL; - uint8_t buffer[RRC_BUF_SIZE] = {0}; uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); ue_p->xids[xid] = RRC_REESTABLISH; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true); int size = do_RRCReestablishment(ctxt_pP, ue_context_pP, - CC_id, + 0 /* CC_id */, buffer, RRC_BUF_SIZE, xid, @@ -1223,12 +1193,8 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc); nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint); - - /* Configure SRB1 for UE */ - nr_pdcp_add_srbs(ctxt_pP->enb_flag, ue_p->rrc_ue_id, SRBs, 0, NULL, NULL); - LOG_D(NR_RRC, "UE %04x --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", ue_p->rnti); freeSRBlist(SRBs); - LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_p->ciphering_algorithm, ue_p->integrity_algorithm); + LOG_I(NR_RRC, "Set PDCP security UE %d RNTI %04x nca %ld nia %d in RRCReestablishment\n", ue_p->rrc_ue_id, ue_p->rnti, ue_p->ciphering_algorithm, ue_p->integrity_algorithm); uint8_t security_mode = enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4); @@ -1240,85 +1206,14 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, kUPenc); nr_pdcp_reestablishment(ctxt_pP->rntiMaybeUEid); - if (!NODE_IS_CU(rrc->node_type)) { - apply_macrlc_config_reest(rrc, ue_context_pP, ctxt_pP, ctxt_pP->rntiMaybeUEid); - } - - nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); -} - -/// @brief Function used in RRCReestablishmentComplete procedure to update the NGU Tunnels. -/// @param reestablish_rnti is the old C-RNTI -void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - const rnti_t reestablish_rnti) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - int i = 0; - int j = 0; - int ret = 0; - - if (get_softmodem_params()->sa) { - LOG_W(NR_RRC, "RRC Reestablishment - Rework identity mapping need to be done properly!\n"); - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; - /* Save e RAB information for later */ - - for (j = 0, i = 0; i < NB_RB_MAX; i++) { - if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) { - create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id; - create_tunnel_req.incoming_rb_id[j] = i + 1; - create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid; - // to be developped, use the first QFI only - create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi; - memcpy(create_tunnel_req.dst_addr[j].buffer, ue_p->pduSession[i].param.upf_addr.buffer, sizeof(uint8_t) * 20); - create_tunnel_req.dst_addr[j].length = ue_p->pduSession[i].param.upf_addr.length; - j++; - } - } - - create_tunnel_req.ue_id = ctxt_pP->rntiMaybeUEid; // warning put zero above - create_tunnel_req.num_tunnels = j; - ret = gtpv1u_update_ngu_tunnel(ctxt_pP->instance, &create_tunnel_req, reestablish_rnti); - - if (ret != 0) { - LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti); - AssertFatal(false, "not implemented\n"); - return; - } - } -} - -/// @brief Function used in RRCReestablishmentComplete procedure to update the NAS PDUSessions and the xid. -/// @param old_xid Refers to the old transaction identifier passed to rrc_gNB_process_RRCReestablishmentComplete as xid. -/// @todo parameters yet to process inside the for loop. -/// @todo should test if pdu session are Ok before! inside the for loop. -void RRCReestablishmentComplete_nas_pdu_update(rrc_gNB_ue_context_t *ue_context_pP, const uint8_t old_xid) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - /* Add all NAS PDUs to the list */ - for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { - ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; - ue_p->pduSession[i].xid = old_xid; - LOG_D(NR_RRC, - "RRC Reestablishment - setting the status for the default DRB (index %d) to (%d,%s)\n", - i, - ue_p->pduSession[i].status, - "PDU_SESSION_STATUS_DONE"); - } -} - -/// @brief Function used in RRCReestablishmentComplete procedure to Free all the NAS PDU buffers. -void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - /* Free all NAS PDUs */ - for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { - if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { - /* Free the NAS PDU buffer and invalidate it */ - free(ue_p->pduSession[i].param.nas_pdu.buffer); - ue_p->pduSession[i].param.nas_pdu.buffer = NULL; - } - } + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + uint32_t old_gNB_DU_ue_id = old_rnti; + f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, + .srb_id = DCCH, + .old_gNB_DU_ue_id = &old_gNB_DU_ue_id}; + deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; + nr_pdcp_data_req_srb(ue_p->rrc_ue_id, DCCH, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); } /// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request. @@ -1326,10 +1221,9 @@ void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP /// @param reestablish_rnti is the old C-RNTI /// @param ue_context_pP UE context container information regarding the UE /// @param xid Transaction Identifier used in RRC messages -void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, - const rnti_t reestablish_rnti, - rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t xid) +static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t xid) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; LOG_I(NR_RRC, @@ -1348,19 +1242,10 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command); LOG_D(NR_RRC, "RRC Reestablishment - set security successfully \n"); } - RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); - RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid); - - /* Update RNTI in ue_context */ - LOG_I(NR_RRC, "RRC Reestablishment - Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); - rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->rrc_ue_id); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - // Revert spCellConfig stored in spCellConfigReestablishment before had been dropped during RRC Reestablishment - ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment; - ue_p->spCellConfigReestablishment = NULL; cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig; cellGroupConfig->mac_CellGroupConfig = ue_p->masterCellGroup->mac_CellGroupConfig; cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig; @@ -1403,32 +1288,13 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx freeDRBlist(DRBs); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); - RRCReestablishmentComplete_nas_pdu_free(ue_context_pP); - - if (size < 0) { - LOG_E(NR_RRC, "RRC decode err!!! do_RRCReconfiguration\n"); - return; - } else { - LOG_I(NR_RRC, - "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n", - ctxt_pP->module_id, - ctxt_pP->frame, - size, - ue_p->rnti); - LOG_D(NR_RRC, - "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfiguration to UE %04x MUI %d) --->][PDCP][MOD " - "%u][RB %u]\n", - ctxt_pP->frame, - ctxt_pP->module_id, - size, - ue_p->rnti, - rrc_gNB_mui, - ctxt_pP->module_id, - DCCH); - - nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, cellGroupConfig); - nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); - } + AssertFatal(size > 0, "cannot encode RRC Reconfiguration\n"); + LOG_I(NR_RRC, + "UE %d RNTI %04x: Generate NR_RRCReconfiguration after reestablishment complete (bytes %d)\n", + ue_p->rrc_ue_id, + ue_p->rnti, + size); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig @@ -1500,7 +1366,6 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP /*------------------------------------------------------------------------------*/ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *msg) { - module_id_t Idx; asn_dec_rval_t dec_rval; NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[module_id]; @@ -1565,13 +1430,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(gnb_rrc_inst, s_tmsi_part1))) { gNB_RRC_UE_t *UE = &ue_context_p->ue_context; LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, old rnti %04x => %04x\n", UE->rnti, rnti); - - // TODO: MAC structures should not be accessed directly from the RRC! An implementation using the F1 interface should be developed. - if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { - nr_rrc_mac_remove_ue(ue_context_p->ue_context.rnti); - } else { - AssertFatal(false, "not implemented: need to switch RNTI in MAC via DL RRC Message Transfer\n"); - } + AssertFatal(false, "not implemented\n"); /* replace rnti in the context */ UE->rnti = rnti; @@ -1653,18 +1512,18 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r break; } - rnti_t c_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; - LOG_I(NR_RRC, "c_RNTI: %04x\n", c_rnti); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, c_rnti); + rnti_t old_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; + // TODO: we need to check within a specific DU! + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, old_rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (ue_context_p == NULL) { LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n"); - xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0); + xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } // c-plane not end if ((UE->StatusRrc != NR_RRC_RECONFIGURED) && (UE->reestablishment_cause == NR_ReestablishmentCause_spare1)) { - LOG_E(NR_RRC, "NR_RRCReestablishmentRequest (UE %x c-plane is not end), RRC establishment failed\n", c_rnti); + AssertFatal(false, "not implemented: is this really a bug?\n"); /* TODO RRC Release ? */ break; } @@ -1672,36 +1531,28 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r /* TODO: start timer in ITTI and drop UE if it does not come back */ (void) xid; /* xid currently not used */ - // Insert C-RNTI to map - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; - LOG_I(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); - if (nr_reestablish_rnti_map->ue_id == 0) { - nr_reestablish_rnti_map->ue_id = rnti; - nr_reestablish_rnti_map->c_rnti = c_rnti; - LOG_W(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x bug in UEid to fix \n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); - break; - } - } + // update with new RNTI, and update secondary UE association + UE->rnti = rnti; + cu_remove_f1_ue_data(UE->rrc_ue_id); + f1_ue_data_t ue_data = {.secondary_ue = rnti}; + cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); UE->reestablishment_cause = cause; LOG_D(NR_RRC, "Accept RRCReestablishmentRequest from UE physCellId %ld cause %ld\n", physCellId, cause); UE->primaryCC_id = 0; - // LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; - Idx = DCCH; - // SRB1 - UE->Srb[1].Active = 1; // SRB2: set it to go through SRB1 with id 1 (DCCH) - UE->Srb[2].Active = 1; - protocol_ctxt_t ctxt = {.rntiMaybeUEid = rnti, .module_id = module_id, .instance = module_id, .enb_flag = 1, .eNB_index = module_id}; + //UE->Srb[2].Active = 1; + protocol_ctxt_t ctxt = {.rntiMaybeUEid = ue_context_p->ue_context.rrc_ue_id, + .module_id = module_id, + .instance = module_id, + .enb_flag = 1, + .eNB_index = module_id}; rrc_gNB_generate_RRCReestablishment(&ctxt, ue_context_p, msg->du2cu_rrc_container, gnb_rrc_inst->carrier.servingcellconfigcommon, - 0); - - LOG_I(NR_RRC, "CALLING RLC CONFIG SRB1 (rbid %d)\n", Idx); + old_rnti); } break; case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: @@ -1760,48 +1611,18 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, } static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_p, const NR_RRCReestablishmentComplete_t *reestablishment_complete) { - rnti_t reestablish_rnti = 0; - gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; - rrc_gNB_ue_context_t *ue_context_p = NULL; - gNB_RRC_UE_t *UE = NULL; - // Select C-RNTI from map - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; - LOG_I(NR_RRC, - "nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n", - i, - nr_reestablish_rnti_map->ue_id, - nr_reestablish_rnti_map->c_rnti, - ctxt_pP->rntiMaybeUEid); - if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { - LOG_I(NR_RRC, - "Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", - i, - nr_reestablish_rnti_map->ue_id, - nr_reestablish_rnti_map->c_rnti); - reestablish_rnti = nr_reestablish_rnti_map->c_rnti; - ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti); - UE = &ue_context_p->ue_context; - break; - } - } - - if (ue_context_p == NULL || UE == NULL) { - LOG_E(RRC, "no UE found for reestablishment. ERROR: should send reply\n"); - return -1; - } + DevAssert(ue_context_p != NULL); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; DevAssert(reestablishment_complete->criticalExtensions.present == NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete); rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, - reestablish_rnti, ue_context_p, reestablishment_complete->rrc_TransactionIdentifier); - nr_rrc_mac_remove_ue(reestablish_rnti); - UE->ue_reestablishment_counter++; return 0; } @@ -1993,8 +1814,11 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ case RRC_DEFAULT_RECONF: rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); break; + case RRC_REESTABLISH_COMPLETE: + /* do nothing */ + break; default: - LOG_E(RRC, "Received unexpected xid: %d\n", xid); + LOG_E(RRC, "Received unexpected transaction type %d for xid %d\n", UE->xids[xid], xid); successful_reconfig = false; break; } @@ -2148,7 +1972,7 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, break; case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: - if (handle_rrcReestablishmentComplete(ctxt_pP, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete) + if (handle_rrcReestablishmentComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete) == -1) return -1; break; diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index e73375fb65..8a8c0bdd2e 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -155,16 +155,6 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_insta return NULL; } -void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, uint32_t rrc_ue_id) -{ - // rnti will need to be a fast access key, with indexing, today it is sequential search - // This function will update the index when it will be made - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, rrc_ue_id); - if (ue_context_p) - ue_context_p->ue_context.rnti = rnti; - else - LOG_E(NR_RRC, "update rnti on a wrong UE id\n"); -} //----------------------------------------------------------------------------- // return a new ue context structure if ue_identityP, rnti not found in collection rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 594b5d2957..3ec0852af6 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -50,7 +50,6 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST* rrc_instance_pP, rrc_gNB_ue_context rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI); -void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, uint32_t gNB_ue_ngap_id); rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP, diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index c7cba3e8e8..f0d89051df 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -254,8 +254,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->secondaryCellGroup); fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.rrc_ue_id); - // the UE context is not yet inserted in the RRC UE manager - // rrc_gNB_update_ue_context_rnti(UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, rrc, UE->rrc_ue_id); UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void *)CG_Config,0,sizeof(*CG_Config)); @@ -379,7 +377,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a nr_pdcp_add_drbs(ctxt.enb_flag, rrc_ue_id, - 0, ue_context_p->ue_context.rb_config->drb_ToAddModList, (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, kUPenc, diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index bf9861ecfb..b3885faada 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1683,7 +1683,6 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, // Refresh DRBs nr_pdcp_add_drbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, - 0, radioBearerConfig->drb_ToAddModList, ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4), kUPenc, diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 5a75b8953a..d7cc496439 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -768,31 +768,31 @@ int gtpv1u_create_ngu_tunnel(const instance_t instance, return !GTPNOK; } -int gtpv1u_update_ngu_tunnel(const instance_t instanceP, const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, const ue_id_t prior_ue_id) +int gtpv1u_update_ue_id(const instance_t instanceP, ue_id_t old_ue_id, ue_id_t new_ue_id) { - LOG_D(GTPU, "[%ld] Update tunnels from UEid %lx to UEid %lx\n", instanceP, prior_ue_id, create_tunnel_req_pP->ue_id); - pthread_mutex_lock(&globGtp.gtp_lock); auto inst = &globGtp.instances[compatInst(instanceP)]; - auto it = inst->ue2te_mapping.find(prior_ue_id); + auto it = inst->ue2te_mapping.find(old_ue_id); if (it == inst->ue2te_mapping.end()) { - LOG_W(GTPU, "[%ld] Delete GTP tunnels for UEid: %lx, but no tunnel exits\n", instanceP, prior_ue_id); + LOG_W(GTPU, "[%ld] Update GTP tunnels for UEid: %lx, but no tunnel exits\n", instanceP, old_ue_id); pthread_mutex_unlock(&globGtp.gtp_lock); return GTPNOK; } - for (int i = 0; i < create_tunnel_req_pP->num_tunnels; i++) { - teid_t incoming_teid = inst->ue2te_mapping[prior_ue_id].bearers[create_tunnel_req_pP->pdusession_id[i]].teid_incoming; - if (globGtp.te2ue_mapping[incoming_teid].ue_id == prior_ue_id) { - globGtp.te2ue_mapping[incoming_teid].ue_id = create_tunnel_req_pP->ue_id; + for (unsigned i = 0; i < it->second.bearers.size(); ++i) { + teid_t incoming_teid = inst->ue2te_mapping[old_ue_id].bearers[i].teid_incoming; + if (globGtp.te2ue_mapping[incoming_teid].ue_id == old_ue_id) { + globGtp.te2ue_mapping[incoming_teid].ue_id = new_ue_id; } } - inst->ue2te_mapping[create_tunnel_req_pP->ue_id] = it->second; + inst->ue2te_mapping[new_ue_id] = it->second; inst->ue2te_mapping.erase(it); pthread_mutex_unlock(&globGtp.gtp_lock); + + LOG_I(GTPU, "[%ld] Updated tunnels from UEid %lx to UEid %lx\n", instanceP, old_ue_id, new_ue_id); return !GTPNOK; } diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index 9592070ca9..f8228677fc 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -76,11 +76,8 @@ extern "C" { int gtpv1u_delete_ngu_tunnel( const instance_t instance, gtpv1u_gnb_delete_tunnel_req_t *req); - - int gtpv1u_update_ngu_tunnel( const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, - const ue_id_t prior_rnti - ); + + int gtpv1u_update_ue_id(const instance_t instanceP, ue_id_t old_ue_id, ue_id_t new_ue_id); // New API teid_t newGtpuCreateTunnel(instance_t instance, From 792cd56f63c00f558d56caf548d3d9cbfb4f3088 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 9 Aug 2023 09:04:36 +0200 Subject: [PATCH 44/47] Cleanup after RRC reestablishment --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 6 +-- openair2/RRC/NR/MESSAGES/asn1_msg.h | 3 +- openair2/RRC/NR/nr_rrc_defs.h | 1 - openair2/RRC/NR/rrc_gNB.c | 57 +++++++++-------------------- 4 files changed, 22 insertions(+), 45 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 65e15ce115..3935c18bfe 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1100,8 +1100,7 @@ uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c } //------------------------------------------------------------------------------ -int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, +int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP, int CC_id, uint8_t *const buffer, size_t buffer_size, @@ -1126,7 +1125,8 @@ int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP, rrcReestablishment->criticalExtensions.present = NR_RRCReestablishment__criticalExtensions_PR_rrcReestablishment; rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1, sizeof(NR_RRCReestablishment_IEs_t)); - uint16_t pci = RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId; + int module_id = 0; + uint16_t pci = RC.nrrrc[module_id]->carrier.physCellId; uint32_t nr_arfcn_dl = (uint64_t)*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB; LOG_I(NR_RRC, "Reestablishment update key pci=%d, earfcn_dl=%u\n", pci, nr_arfcn_dl); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 27782d8a97..5e9a9fa756 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -172,8 +172,7 @@ uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti); -int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, +int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP, int CC_id, uint8_t *const buffer, size_t buffer_size, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index e05202e553..f9c821736c 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -235,7 +235,6 @@ typedef enum { } rrc_action_t; typedef struct gNB_RRC_UE_s { - uint8_t primaryCC_id; drb_t established_drbs[MAX_DRBS_PER_UE]; uint8_t DRB_active[MAX_DRBS_PER_UE]; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 1696671949..2988acb5ac 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1151,19 +1151,14 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co } //----------------------------------------------------------------------------- -static void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, +static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context_pP, const uint8_t *masterCellGroup_from_DU, NR_ServingCellConfigCommon_t *scc, const rnti_t old_rnti) //----------------------------------------------------------------------------- { - // int UE_id = -1; - // NR_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL; - // NR_SRB_ToAddMod_t *SRB1_config = NULL; - // rrc_gNB_carrier_data_t *carrier = NULL; - module_id_t module_id = ctxt_pP->module_id; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; + module_id_t module_id = 0; + gNB_RRC_INST *rrc = RC.nrrrc[module_id]; int enable_ciphering = 0; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; @@ -1171,8 +1166,7 @@ static void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); ue_p->xids[xid] = RRC_REESTABLISH; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true); - int size = do_RRCReestablishment(ctxt_pP, - ue_context_pP, + int size = do_RRCReestablishment(ue_context_pP, 0 /* CC_id */, buffer, RRC_BUF_SIZE, @@ -1198,13 +1192,13 @@ static void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, uint8_t security_mode = enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4); - nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, + nr_pdcp_config_set_security(ue_p->rrc_ue_id, DCCH, security_mode, kRRCenc, kRRCint, kUPenc); - nr_pdcp_reestablishment(ctxt_pP->rntiMaybeUEid); + nr_pdcp_reestablishment(ue_p->rrc_ue_id); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); uint32_t old_gNB_DU_ue_id = old_rnti; @@ -1482,24 +1476,25 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r const NR_ReestablishmentCause_t cause = rrcReestablishmentRequest.reestablishmentCause; const long physCellId = rrcReestablishmentRequest.ue_Identity.physCellId; LOG_I(NR_RRC, - "UE %04x NR_RRCReestablishmentRequest cause %s\n", + "UE %04x physCellId %ld NR_RRCReestablishmentRequest cause %s\n", rnti, - ((cause == NR_ReestablishmentCause_otherFailure) ? "Other Failure" - : (cause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure" - : "reconfigurationFailure")); - uint8_t xid = -1; + physCellId, + cause == NR_ReestablishmentCause_otherFailure + ? "Other Failure" + : (cause == NR_ReestablishmentCause_handoverFailure ? "Handover Failure" : "reconfigurationFailure")); if (physCellId != gnb_rrc_inst->carrier.physCellId) { /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */ LOG_E(NR_RRC, " NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%ld), fallback to RRC establishment\n", physCellId, gnb_rrc_inst->carrier.physCellId); - xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); + /* 38.401 8.7: "If the UE accessed from a gNB-DU other than the + * original one, the gNB-CU should trigger the UE Context Setup + * procedure" we did not implement this yet; TBD for Multi-DU */ + AssertFatal(false, "not implemented\n"); break; } - LOG_I(NR_RRC, "physCellId: %ld\n", physCellId); - for (int i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n", i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]); } @@ -1508,7 +1503,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) { /* c_RNTI range error should not happen */ LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n"); - xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } @@ -1518,18 +1513,11 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (ue_context_p == NULL) { LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n"); - xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); - break; - } - // c-plane not end - if ((UE->StatusRrc != NR_RRC_RECONFIGURED) && (UE->reestablishment_cause == NR_ReestablishmentCause_spare1)) { - AssertFatal(false, "not implemented: is this really a bug?\n"); - /* TODO RRC Release ? */ + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } /* TODO: start timer in ITTI and drop UE if it does not come back */ - (void) xid; /* xid currently not used */ // update with new RNTI, and update secondary UE association UE->rnti = rnti; @@ -1540,16 +1528,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r UE->reestablishment_cause = cause; LOG_D(NR_RRC, "Accept RRCReestablishmentRequest from UE physCellId %ld cause %ld\n", physCellId, cause); - UE->primaryCC_id = 0; - // SRB2: set it to go through SRB1 with id 1 (DCCH) - //UE->Srb[2].Active = 1; - protocol_ctxt_t ctxt = {.rntiMaybeUEid = ue_context_p->ue_context.rrc_ue_id, - .module_id = module_id, - .instance = module_id, - .enb_flag = 1, - .eNB_index = module_id}; - rrc_gNB_generate_RRCReestablishment(&ctxt, - ue_context_p, + rrc_gNB_generate_RRCReestablishment(ue_context_p, msg->du2cu_rrc_container, gnb_rrc_inst->carrier.servingcellconfigcommon, old_rnti); From 979ebdeb42ff25a592433016e00de9e728d1f815 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 9 Aug 2023 09:39:47 +0200 Subject: [PATCH 45/47] Implement RRC Reestablishment fallback with RRC Setup --- openair2/RRC/NR/rrc_gNB.c | 123 +++++++------------------------------- 1 file changed, 20 insertions(+), 103 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 2988acb5ac..1fa458a309 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -187,26 +187,6 @@ static void freeDRBlist(NR_DRB_ToAddModList_t *list) //ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, list); return; } -static void nr_rrc_addmod_srbs(int rnti, - const NR_SRB_INFO_TABLE_ENTRY *srb_list, - const int nb_srb, - const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list) -{ - if (srb_list == NULL || bearer_list == NULL) - return; - - for (int i = 0; i < nb_srb; i++) { - if (srb_list[i].Active) - for (int j = 0; j < bearer_list->list.count; j++) { - const NR_RLC_BearerConfig_t *bearer = bearer_list->list.array[j]; - if (bearer->servedRadioBearer != NULL - && bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity - && i == bearer->servedRadioBearer->choice.srb_Identity) { - nr_rlc_add_srb(rnti, i, bearer); - } - } - } -} static void nr_rrc_addmod_drbs(int rnti, const NR_DRB_ToAddModList_t *drb_list, @@ -447,17 +427,6 @@ static void freeSRBlist(NR_SRB_ToAddModList_t *l) LOG_E(NR_RRC, "Call free SRB list on NULL pointer\n"); } -static void apply_macrlc_config(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP) -{ - NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL; - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - nr_rrc_mac_update_cellgroup(ue_p->rnti, cgc); - nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, ue_p->Srb, maxSRBs, cgc->rlc_BearerToAddModList); - NR_DRB_ToAddModList_t *DRBs = fill_DRB_configList(ue_p); - nr_rrc_addmod_drbs(ctxt_pP->rntiMaybeUEid, DRBs, cgc->rlc_BearerToAddModList); - freeDRBlist(DRBs); -} - //----------------------------------------------------------------------------- static void rrc_gNB_generate_RRCSetup(instance_t instance, rnti_t rnti, @@ -497,68 +466,6 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); } -//----------------------------------------------------------------------------- -static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t module_id, rnti_t rnti, const int CC_id) -//----------------------------------------------------------------------------- -{ - LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n"); - rrc_gNB_ue_context_t *ue_context_pP = NULL; - gNB_RRC_INST *rrc_instance_p = RC.nrrrc[module_id]; - - AssertFatal(false, "this is not implemented\n"); - /* for creating a UE context, we need the DU ID to be able to indicate the - * DU. This is not yet implemented for Reestablishment. We know that in - * monolithic, the DU UE ID is the RNTI, so use that for the moment */ - ue_context_pP = rrc_gNB_create_ue_context(rnti, rrc_instance_p, 0, rnti); - - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - unsigned char buf[1024]; - uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); - ue_p->xids[xid] = RRC_SETUP_FOR_REESTABLISHMENT; - NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true); - - int size = do_RRCSetup(ue_context_pP, buf, xid, NULL, 0, &rrc_instance_p->configuration, SRBs); - AssertFatal(size > 0, "do_RRCSetup failed\n"); - AssertFatal(size <= 1024, "memory corruption\n"); - - AssertFatal(size>0,"Error generating RRCSetup for RRCReestablishmentRequest\n"); - - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, - (char *)buf, - size, - "[MSG] RRC Setup\n"); - - LOG_D(NR_RRC, "RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB for rnti %04x\n", rnti); - freeSRBlist(SRBs); - - // update SCC and MIB/SIB (two calls) - nr_mac_config_scc(RC.nrmac[rrc_instance_p->module_id], - rrc_instance_p->configuration.pdsch_AntennaPorts, - rrc_instance_p->configuration.pusch_AntennaPorts, - rrc_instance_p->configuration.sib1_tda, - rrc_instance_p->configuration.minRXTXTIME, - rrc_instance_p->carrier.servingcellconfigcommon); - nr_mac_config_mib(RC.nrmac[rrc_instance_p->module_id], rrc_instance_p->carrier.mib); - nr_mac_config_sib1(RC.nrmac[rrc_instance_p->module_id], rrc_instance_p->carrier.siblock1); - - LOG_I(NR_RRC, " [RAPROC] rnti: %04x Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", rnti, size); - // configure MAC - protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, ue_p->rrc_ue_id, 0, 0); - apply_macrlc_config(rrc_instance_p, ue_context_pP, &ctxt); - - f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); - f1ap_dl_rrc_message_t dl_rrc = { - .gNB_CU_ue_id = ue_p->rrc_ue_id, - .gNB_DU_ue_id = ue_data.secondary_ue, - .rrc_container = buf, - .rrc_container_length = size, - .srb_id = CCCH - }; - rrc_instance_p->mac_rrc.dl_rrc_message_transfer(&dl_rrc); - return xid; -} - static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP) //----------------------------------------------------------------------------- { @@ -1499,21 +1406,31 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n", i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]); } - // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values - if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) { - /* c_RNTI range error should not happen */ - LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n"); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); - break; - } - rnti_t old_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; // TODO: we need to check within a specific DU! rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, old_rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + /* in case we need to do RRC Setup, give the UE a new random identity */ + uint64_t random_value; + fill_random(&random_value, sizeof(random_value)); + random_value = random_value & 0x7fffffffff; /* random value is 39 bits */ if (ue_context_p == NULL) { - LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n"); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); + LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC setup\n"); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); + ue_context_p->ue_context.Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(module_id, rnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); + break; + } + + // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values + if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) { + /* c_RNTI range error should not happen */ + LOG_E(NR_RRC, + "NR_RRCReestablishmentRequest c_RNTI %04lx range error, fallback to RRC setup\n", + rrcReestablishmentRequest.ue_Identity.c_RNTI); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); + ue_context_p->ue_context.Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(module_id, rnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); break; } From d0bfaf4dcb2d699d4500514046df897c1ba03803 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 9 Aug 2023 10:00:44 +0200 Subject: [PATCH 46/47] Verify reestablishment in DU-CU split --- .../container_sa_f1_b200_quectel.xml | 21 ++++++++++++++++++- .../sa_f1_b200_gnb/docker-compose.yml | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml index a20ea8845e..1f28fce309 100644 --- a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml @@ -39,6 +39,10 @@ 110011 110001 150001 + 160001 + 100002 + 160002 + 150001 110011 110001 150000 @@ -114,7 +118,7 @@ IdleSleep Sleep - 20 + 10 @@ -184,6 +188,21 @@ single-ue + + Custom_Command + Trigger Reestablishment (on DU) + ofqot + echo ci force_reestab | nc -N 192.168.68.195 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' + yes + + + Custom_Command + Verify Reestablishment (on CU) + ofqot + echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + yes + + Undeploy_Object Undeploy CU-DU diff --git a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml index e40dc686d7..2be92cdb38 100644 --- a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml @@ -6,7 +6,7 @@ services: privileged: true container_name: sa-cu-gnb environment: - USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time,line_num,function + USE_ADDITIONAL_OPTIONS: --sa --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function volumes: - ../../conf_files/gnb-cu.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf networks: @@ -26,7 +26,7 @@ services: container_name: sa-du-b200-gnb environment: USE_B2XX: 'yes' - USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14 + USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14 volumes: - ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf - /dev:/dev From a082f708b6870e31c4314ce41a2671c3a0342448 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 12 Aug 2023 13:43:36 +0200 Subject: [PATCH 47/47] Fix: link T into oai_eth_transpro Via the include of the logging system, the ethernet transport library implicitly depends on T. Hence, link T into oai_eth_transpro. --- radio/ETHERNET/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/radio/ETHERNET/CMakeLists.txt b/radio/ETHERNET/CMakeLists.txt index 52aebdcc1a..8c6590c6e9 100644 --- a/radio/ETHERNET/CMakeLists.txt +++ b/radio/ETHERNET/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(oai_eth_transpro MODULE eth_udp.c eth_raw.c ) +target_link_libraries(oai_eth_transpro PRIVATE ${T_LIB}) target_include_directories(oai_eth_transpro PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) set_target_properties(oai_eth_transpro PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) add_custom_command(TARGET oai_eth_transpro POST_BUILD