From 97d989a865f49be1238d2f64bbeb35726ad83499 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 7 Mar 2023 16:46:58 +0100 Subject: [PATCH] Add telnet module with CI-specific functions - adds function to retrieve the only UE's RNTI - adds function to trigger reestablishment for the only UE present, or a specific via its RNTI - adds function to verify the reestablishment counters --- common/utils/telnetsrv/CMakeLists.txt | 7 +- common/utils/telnetsrv/DOC/telnetusage.md | 2 +- common/utils/telnetsrv/telnetsrv_ci.c | 133 ++++++++++++++++++++++ 3 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 common/utils/telnetsrv/telnetsrv_ci.c diff --git a/common/utils/telnetsrv/CMakeLists.txt b/common/utils/telnetsrv/CMakeLists.txt index 7994a1d151..d310e1162c 100644 --- a/common/utils/telnetsrv/CMakeLists.txt +++ b/common/utils/telnetsrv/CMakeLists.txt @@ -54,8 +54,13 @@ add_library(telnetsrv_5Gue MODULE telnetsrv_5Gue_measurements.c) add_dependencies(telnetsrv telnetsrv_5Gue) target_link_libraries(telnetsrv_5Gue PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) +message(STATUS "Add CI specific telnet functions in libtelnetsrv_ci.so") +add_library(telnetsrv_ci MODULE telnetsrv_ci.c) +target_link_libraries(telnetsrv_ci PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) +add_dependencies(telnetsrv telnetsrv_ci) + # all libraries should be written to root build dir -set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue +set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../../.. ) diff --git a/common/utils/telnetsrv/DOC/telnetusage.md b/common/utils/telnetsrv/DOC/telnetusage.md index 8b8179fa2b..af509f8648 100644 --- a/common/utils/telnetsrv/DOC/telnetusage.md +++ b/common/utils/telnetsrv/DOC/telnetusage.md @@ -8,7 +8,7 @@ By default the embedded telnet server, which is implemented in a shared library, ./build_oai --build-lib telnetsrv ``` -This will create the `libtelnetsrv.so` and `libtelnetsrv_ file in the `cmake_targets/ran_build/build` subdirectory of the oai repository. can be "enb", "gnb", "4GUE" or "5GUE", each library containing functions specific to a given executable. +This will create the `libtelnetsrv.so` and `libtelnetsrv_ file in the `cmake_targets/ran_build/build` subdirectory of the oai repository. can be "enb", "gnb", "4GUE", "5GUE", or "ci", each library containing functions specific to a given executable. When starting the softmodem, you must specify the **_\-\-telnetsrv_** option to load and start the telnet server. The telnet server is loaded via the [oai shared library loader](loader). diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c new file mode 100644 index 0000000000..b7c19f6c8e --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -0,0 +1,133 @@ +/* + * 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 +#include +#include +#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" + +#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) +{ + NR_UE_info_t *ue = NULL; + UE_iterator(RC.nrmac[0]->UE_info.list, it) { + if (it && ue) + return -1; + if (it) + ue = it; + } + if (!ue) + return -1; + + // verify it exists in RRC as well + rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context(RC.nrrrc[0], ue->rnti); + if (!rrcue) + return -1; + + return ue->rnti; +} + +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(); + if (rnti < 1) + ERROR_MSG_RET("different number of UEs\n"); + + prnt("single UE RNTI %04x\n", rnti); + return 0; +} + +int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) +{ + int rnti = -1; + if (!buf) { + rnti = get_single_ue_rnti(); + if (rnti < 1) + ERROR_MSG_RET("no UE found\n"); + } else { + rnti = strtol(buf, NULL, 16); + if (rnti < 1 || rnti >= 0xfffe) + ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); + } + + rrc_gNB_ue_context_t *ue = rrc_gNB_get_ue_context(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.ue_reestablishment_counter, + ue->ue_context.ue_reconfiguration_after_reestablishment_counter); + return 0; +} + +int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) +{ + int rnti = -1; + if (!buf) { + rnti = get_single_ue_rnti(); + if (rnti < 1) + ERROR_MSG_RET("no UE found\n"); + } else { + rnti = strtol(buf, NULL, 16); + if (rnti < 1 || rnti >= 0xfffe) + 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(RC.nrrrc[0], rnti); + if (!rrcue) + ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); + + nr_rlc_remove_ue(rnti); + prnt("force-remove UE RNTI %04x from RLC to trigger reestablishment\n", rnti); + return 0; +} + +static telnetshell_cmddef_t cicmds[] = { + {"get_single_rnti", "", get_single_rnti}, + {"force_reestab", "[rnti(hex,opt)]", trigger_reestab}, + {"get_reestab_count", "[rnti(hex,opt)]", get_reestab_count}, + {"", "", NULL}, +}; + +static telnetshell_vardef_t civars[] = { + + {"", 0, 0, NULL} +}; + +void add_ci_cmds(void) { + add_telnetcmd("ci", civars, cicmds); +}