From 4f884ab172c305b8afb42aecb2c7a617f7a044c3 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 19 Mar 2024 08:43:12 +0100 Subject: [PATCH 01/19] bugfix: unlocking RLC manager in nr_rlc_get_lcid_from_rb function --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index b8fd148876..409f1599ab 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -114,14 +114,19 @@ logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id) for (logical_chan_id_t id = 1; id <= 32; id++) { nr_rlc_rb_t *rb = &ue->lcid2rb[id - 1]; if (is_srb) { - if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id) + if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id) { + nr_rlc_manager_unlock(nr_rlc_ue_manager); return id; + } } else { - if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id) + if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id) { + nr_rlc_manager_unlock(nr_rlc_ue_manager); return id; + } } } LOG_E(RLC, "Couldn't find LCID corresponding to %s %d\n", is_srb ? "SRB" : "DRB", rb_id); + nr_rlc_manager_unlock(nr_rlc_ue_manager); return 0; } From 6beeb6eef1b3a60303bcdd4b05362973caf6396d Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 18 Dec 2023 14:48:34 +0100 Subject: [PATCH 02/19] handle rlf with re-establishment or going to idle --- openair2/RRC/NR_UE/rrc_UE.c | 20 +++++++++++++++++++ openair2/RRC/NR_UE/rrc_proto.h | 1 + openair2/RRC/NR_UE/rrc_timers_and_constants.c | 3 +-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 53364b0768..5a65dcd71d 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -2285,6 +2285,26 @@ void handle_RRCRelease(NR_UE_RRC_INST_t *rrc) asn1cFreeStruc(asn_DEF_NR_RRCRelease, rrc->RRCRelease); } +void handle_rlf_detection(NR_UE_RRC_INST_t *rrc) +{ + // 5.3.10.3 in 38.331 + bool srb2 = rrc->Srb[2] != RB_NOT_PRESENT; + bool any_drb = false; + for (int i = 0; i < MAX_DRBS_PER_UE; i++) { + if (rrc->status_DRBs[i] != RB_NOT_PRESENT) { + any_drb = true; + break; + } + } + + if (rrc->as_security_activated && srb2 && any_drb) // initiate the connection re-establishment procedure + nr_rrc_initiate_rrcReestablishment(rrc, NR_ReestablishmentCause_otherFailure, 0); + else { + NR_Release_Cause_t cause = rrc->as_security_activated ? RRC_CONNECTION_FAILURE : OTHER; + nr_rrc_going_to_IDLE(rrc, cause, NULL); + } +} + void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, NR_Release_Cause_t release_cause, NR_RRCRelease_t *RRCRelease) diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 95685c8e2f..28b51d5320 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -63,6 +63,7 @@ void *rrc_nrue_task(void *args_p); void *rrc_nrue(void *args_p); void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc); +void handle_rlf_detection(NR_UE_RRC_INST_t *rrc); /**\brief RRC NSA UE task. \param void *args_p Pointer on arguments to start the task. */ diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index f0635b16b2..7e0c040731 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -157,10 +157,9 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc) bool t310_expired = nr_timer_tick(&timers->T310); if(t310_expired) { LOG_W(NR_RRC, "Timer T310 expired\n"); - // TODO // handle detection of radio link failure // as described in 5.3.10.3 of 38.331 - AssertFatal(false, "Radio link failure! Not handled yet!\n"); + handle_rlf_detection(rrc); } bool t311_expired = nr_timer_tick(&timers->T311); From f380a48a3b05199834c1adf3e6f7c3d8501e62eb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Mar 2024 16:53:54 +0100 Subject: [PATCH 03/19] RLC: add per-UE RLF callback If the RLC cannot retransmit a package, 3GPP specs say that we should declare radio link failure (RLF). Up to this commit, the code did nothing though. In this commit, add a per-UE RLF callback; the RLC will call into this function to signal that RLF has been detected through maximum retransmissions on a particular RLC bearer. --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 31 ++++++++-------------- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h | 2 ++ openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h | 3 +++ 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 409f1599ab..16dae866ce 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -619,10 +619,6 @@ static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity) int i; int is_srb; int rb_id; -#if 0 - MessageDef *msg; -#endif - int is_enb; /* is it SRB? */ for (i = 0; i < 2; i++) { @@ -650,23 +646,18 @@ rb_found: is_srb ? "SRB" : "DRB", rb_id); - /* TODO: do something for DRBs? */ - if (is_srb == 0) - return; + if (ue->rlf_handler) + ue->rlf_handler(ue->ue_id); + else + LOG_W(RLC, "UE %04x: RLF detected, but no callable RLF handler registered\n", ue->ue_id); +} - is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); - if (!is_enb) - return; - -#if 0 - msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION); - RLC_SDU_INDICATION(msg).rnti = ue->rnti; - RLC_SDU_INDICATION(msg).is_successful = 0; - RLC_SDU_INDICATION(msg).srb_id = rb_id; - RLC_SDU_INDICATION(msg).message_id = -1; - /* TODO: accept more than 1 instance? here we send to instance id 0 */ - itti_send_msg_to_task(TASK_RRC_ENB, 0, msg); -#endif +void nr_rlc_set_rlf_handler(int ue_id, rlf_handler_t rlf_h) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); + ue->rlf_handler = rlf_h; + nr_rlc_manager_unlock(nr_rlc_ue_manager); } void nr_rlc_reestablish_entity(int ue_id, int lc_id) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 736c42a0b7..10182f3793 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -44,6 +44,8 @@ struct NR_LogicalChannelConfig; void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); +void nr_rlc_set_rlf_handler(int ue_id, rlf_handler_t rlf_h); + logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id); void nr_rlc_reestablish_entity(int ue_id, int lc_id); void nr_rlc_remove_ue(int ue_id); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h index e37d7929d8..13f5c55a2f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -37,12 +37,15 @@ typedef struct nr_rlc_rb_t { } choice; } nr_rlc_rb_t; +typedef void (*rlf_handler_t)(int rnti); + typedef struct nr_rlc_ue_t { int ue_id; nr_rlc_entity_t *srb0; nr_rlc_entity_t *srb[3]; nr_rlc_entity_t *drb[MAX_DRBS_PER_UE]; nr_rlc_rb_t lcid2rb[32]; + rlf_handler_t rlf_handler; } nr_rlc_ue_t; /***********************************************************************/ From eee4a0c6523c674cad4fe08dea2ce6469ad539f8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Mar 2024 18:56:08 +0100 Subject: [PATCH 04/19] UE: signal RLF to RRC --- openair2/COMMON/rrc_messages_def.h | 3 +++ openair2/COMMON/rrc_messages_types.h | 6 ++++++ openair2/RRC/NR_UE/rrc_UE.c | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index ef09d98284..fb94aeb29e 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -85,3 +85,6 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr // eNB: RLC -> RRC messages MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication) MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, nas_pdu_session_req_t, nas_pdu_session_req) + +// UE: RLC -> RRC messages +MESSAGE_DEF(NR_RRC_RLC_MAXRTX, MESSAGE_PRIORITY_MED, RlcMaxRtxIndication, nr_rlc_maxrtx_indication) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 15509b1807..0e57120ee4 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -97,6 +97,8 @@ #define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa #define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req +#define NR_RRC_RLC_MAXRTX(mSGpTR) (mSGpTR)->ittiMsg.nr_rlc_maxrtx_indication + //-------------------------------------------------------------------------------------------// typedef struct RrcStateInd_s { Rrc_State_t state; @@ -453,4 +455,8 @@ typedef struct rlc_sdu_indication_s { int message_id; } RlcSduIndication; +typedef struct { + int ue_id; +} RlcMaxRtxIndication; + #endif /* RRC_MESSAGES_TYPES_H_ */ diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 5a65dcd71d..602795bc4c 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -873,6 +873,13 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, return 0; } +static void nr_rrc_signal_maxrtxindication(int ue_id) +{ + MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX); + NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id; + itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg); +} + static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, const NR_CellGroupConfig_t *cellGroupConfig) { @@ -901,9 +908,11 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer); + nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); } else { // DRB NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity; nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer); + nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); } } } @@ -1843,6 +1852,15 @@ void *rrc_nrue(void *notUsed) nr_rrc_going_to_IDLE(rrc, release_cause, NULL); break; + case NR_RRC_RLC_MAXRTX: + // detection of RLF upon indication from RLC that the maximum number of retransmissions has been reached + LOG_W(NR_RRC, + "[UE %ld ID %d] Received indication that RLC reached max retransmissions\n", + instance, + NR_RRC_RLC_MAXRTX(msg_p).ue_id); + handle_rlf_detection(rrc); + break; + case NR_RRC_MAC_MSG3_IND: nr_rrc_handle_msg3_indication(rrc, NR_RRC_MAC_MSG3_IND(msg_p).rnti); break; From ca877514aaac78e5f2820c3fc325dae6eebf8814 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 22 Mar 2024 16:13:34 +0100 Subject: [PATCH 05/19] fix for going to idle: release MAC config only after resetting MAC --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 3c66515eef..80e2255aa5 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1611,8 +1611,7 @@ static void configure_timeAlignmentTimer(NR_timer_t *time_alignment_timer, NR_Ti nr_timer_start(time_alignment_timer); } -void nr_rrc_mac_config_req_reset(module_id_t module_id, - NR_UE_MAC_reset_cause_t cause) +void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -1621,8 +1620,8 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, switch (cause) { case GO_TO_IDLE: reset_ra(mac, true); - release_mac_configuration(mac, cause); nr_ue_init_mac(mac); + release_mac_configuration(mac, cause); nr_ue_mac_default_configs(mac); // new sync but no target cell id -> -1 nr_ue_send_synch_request(mac, module_id, 0, &sync_req); From 2cc63bf19509dd965394d1d552d3533d29c0a6b4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 6 Jun 2024 13:06:54 +0200 Subject: [PATCH 06/19] Fixup: avoid deadlock --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 16dae866ce..3b0847feae 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -667,6 +667,7 @@ void nr_rlc_reestablish_entity(int ue_id, int lc_id) if (ue == NULL) { LOG_E(RLC, "RLC instance for the given UE was not found \n"); + nr_rlc_manager_unlock(nr_rlc_ue_manager); return; } nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id); From 0bbd446478f7464786682752896c4a9e5f95796e Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 11 Jun 2024 11:45:16 +0200 Subject: [PATCH 07/19] Add test to trigger re-establishment to RFSIM F1 CI * trigger re-establshemnt on DU: reset RLC counters on DRB 1 for OAI UE, since SRB 1 does not work for lack of periodic measurements reports * how is the re-establishment triggered? * a transmission on DRB 1 occurs * detection of a mismatch of RLC counters at the UE side * max number of RLC retransmissions reached * RLF detection * verify re-establishment on CU: we ping the core from the UE; this sends packets on DRB, and because the sequence number mismatches, will trigger a reestablishment. We accept in the ping that a couple of packets might be lost; after ping is over, reestablishment must be done as well (else the ping will already fail). --- .../xml_files/container_5g_f1_rfsim.xml | 30 +++++++++++++++++++ .../5g_f1_rfsimulator/docker-compose.yaml | 6 +++- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 13 ++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 16c02050d2..93ad2c4c94 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -34,6 +34,11 @@ 030020 030021 030022 + 040001 + 020022 + 040002 + 030021 + 030022 100021 222222 @@ -117,6 +122,31 @@ 90 + + Custom_Command + Trigger Reestablishment + cacofonix + echo ci force_reestab | nc 192.168.71.171 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' + yes + + + + Ping + Ping ext-dn from all NR-UEs + rfsim5g_ue + cacofonix + -c 20 192.168.72.135 -i0.5 -w25 + 80 + + + + Custom_Command + Verify Reestablishment + cacofonix + echo ci get_reestab_count | nc 192.168.71.150 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + yes + + Custom_Command Simulate a disruption of DL radio channel (ploss 55)(5 sec) diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index c925af1adb..4460452f11 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -87,8 +87,11 @@ services: container_name: rfsim5g-oai-cu cap_drop: - ALL - environment: + environment: USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,time + --rfsimulator.options chanmod + --telnetsrv --telnetsrv.listenaddr 192.168.71.150 + --telnetsrv.shrmod ci ASAN_OPTIONS: detect_leaks=0 depends_on: - oai-ext-dn @@ -113,6 +116,7 @@ services: --log_config.global_log_options level,nocolor,time --rfsimulator.options chanmod --telnetsrv --telnetsrv.listenaddr 192.168.71.171 + --telnetsrv.shrmod ci ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 depends_on: - oai-cu diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 3b0847feae..2ebd18f5e7 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -1096,8 +1096,14 @@ bool nr_rlc_update_id(int from_id, int to_id) return true; } -/* This function is for testing purposes. At least on a COTS UE, it will - * trigger a reestablishment. */ +/** + * @brief This function is for testing purposes. + * Re-establishment is triggered by resetting RLC counters of the bearer, + * which leads to UE reaching maximum RLC retransmissions, RLF detection + * and RRC triggering re-sync. It is assumed that there is ongoing traffic on the bearer. + * - With COTS UEs, triggers re-establishment on SRB 1, where periodical measurement reports are sent. + * - With OAI UE, triggers re-establishment on DRB 1, assuming there is ongoing data traffic. + */ void nr_rlc_test_trigger_reestablishment(int ue_id) { nr_rlc_manager_lock(nr_rlc_ue_manager); @@ -1111,6 +1117,9 @@ void nr_rlc_test_trigger_reestablishment(int ue_id) * as the UE context is created. */ nr_rlc_entity_t *ent = ue->srb[0]; ent->reestablishment(ent); + /* Trigger re-establishment on OAI UE */ + nr_rlc_entity_t *drb = ue->drb[0]; + drb->reestablishment(drb); nr_rlc_manager_unlock(nr_rlc_ue_manager); } From fb1f2539e8eaf8ef0a435ac026a2e52157ddcacb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 16 Oct 2024 15:01:31 +0200 Subject: [PATCH 08/19] Custom_Command nc on cacofonix: cannot use -N, is openBSD --- ci-scripts/xml_files/container_5g_f1_rfsim.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 93ad2c4c94..8c925cbc5f 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -151,7 +151,7 @@ Custom_Command Simulate a disruption of DL radio channel (ploss 55)(5 sec) cacofonix - echo channelmod modify 0 ploss 55 | nc -N 192.168.71.181 8091 && sleep 5 + echo channelmod modify 0 ploss 55 | nc 192.168.71.181 8091 && sleep 5 yes @@ -159,7 +159,7 @@ Custom_Command Get UE sync state (UE ID 0) cacofonix - echo ciUE sync_state 0 | nc -N 192.168.71.181 8091 | grep -E UE_NOT_SYNC + echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_NOT_SYNC yes @@ -167,7 +167,7 @@ Custom_Command Restoration of the original DL channel conditions (ploss 0)(5 sec) cacofonix - echo channelmod modify 0 ploss 0 | nc -N 192.168.71.181 8091 && sleep 5 + echo channelmod modify 0 ploss 0 | nc 192.168.71.181 8091 && sleep 5 yes @@ -175,7 +175,7 @@ Custom_Command Get UE sync state (UE ID 0) cacofonix - echo ciUE sync_state 0 | nc -N 192.168.71.181 8091 | grep -E UE_CONNECTED && sleep 10 + echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_CONNECTED && sleep 10 yes From 59bf54c9cd8e41a0e7b595f4a1ea367838ec21cd Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 29 Jul 2024 11:54:09 +0200 Subject: [PATCH 09/19] Make a separate function to fetch RNTI in telnet CI --- common/utils/telnetsrv/telnetsrv_ci.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 700ff73135..8fcea82fd2 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -115,10 +115,8 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) return 0; } -int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) +int fetch_rnti(char *buf, 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_mac(); @@ -129,9 +127,15 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) if (rnti < 1 || rnti >= 0xfffe) ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); } + return rnti; +} +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 = fetch_rnti(buf, prnt); nr_rlc_test_trigger_reestablishment(rnti); - prnt("Reset RLC counters of UE RNTI %04x to trigger reestablishment\n", rnti); return 0; } From 60ef7f04aa485f825a42fbce8819353762279984 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 29 Jul 2024 11:54:53 +0200 Subject: [PATCH 10/19] Add new ci telnet commands to force UE release and UL failure --- common/utils/telnetsrv/telnetsrv_ci.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 8fcea82fd2..ba3062178f 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -37,6 +37,7 @@ #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" +#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #define TELNETSERVERCODE #include "telnetsrv.h" @@ -167,7 +168,27 @@ int rrc_gNB_trigger_f1_ho(char *buf, int debug, telnet_printfunc_t prnt) gNB_RRC_UE_t *UE = &ue->ue_context; nr_HO_F1_trigger_telnet(RC.nrrrc[0], UE->rrc_ue_id); prnt("RRC F1 handover triggered for UE %u\n", UE->rrc_ue_id); + return 0; +} +int force_ul_failure(char *buf, int debug, telnet_printfunc_t prnt) +{ + if (!RC.nrmac) + ERROR_MSG_RET("no MAC/RLC present, force_ul_failure failed\n"); + int rnti = fetch_rnti(buf, prnt); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); + nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); + return 0; +} + +int force_ue_release(char *buf, int debug, telnet_printfunc_t prnt) +{ + force_ul_failure(buf, debug, prnt); + int rnti = fetch_rnti(buf, prnt); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + sched_ctrl->ul_failure_timer = 2; + nr_mac_check_ul_failure(RC.nrmac[0], UE->rnti, sched_ctrl); return 0; } @@ -175,6 +196,8 @@ 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}, + {"force_ue_release", "[rnti(hex,opt)]", force_ue_release}, + {"force_ul_failure", "[rnti(hex,opt)]", force_ul_failure}, {"trigger_f1_ho", "[rrc_ue_id(int,opt)]", rrc_gNB_trigger_f1_ho}, {"", "", NULL}, }; From 1692e00d4a47990201a062040359f60c18fba6d6 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jul 2024 17:51:08 +0200 Subject: [PATCH 11/19] Add function to fetch RRC UE instance --- openair2/RRC/NR_UE/rrc_UE.c | 5 +++++ openair2/RRC/NR_UE/rrc_proto.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 602795bc4c..13e5965d75 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -151,6 +151,11 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers); +NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance) +{ + return &NR_UE_rrc_inst[instance]; +} + static NR_RB_status_t get_DRB_status(const NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id) { AssertFatal(drb_id > 0 && drb_id < 33, "Invalid DRB ID %ld\n", drb_id); diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 28b51d5320..d1f1d3228f 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -42,7 +42,7 @@ #include "common/utils/ocp_itti/intertask_interface.h" NR_UE_RRC_INST_t *nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx); - +NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance); void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file); void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len); From 882712ffd86824bb78d4af5fc4edd739fb5bf6fb Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jul 2024 17:40:41 +0200 Subject: [PATCH 12/19] Add ciUE telnet command to force RLF --- common/utils/telnetsrv/telnetsrv_ciUE.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/utils/telnetsrv/telnetsrv_ciUE.c b/common/utils/telnetsrv/telnetsrv_ciUE.c index 673d904969..4cecd23272 100644 --- a/common/utils/telnetsrv/telnetsrv_ciUE.c +++ b/common/utils/telnetsrv/telnetsrv_ciUE.c @@ -36,6 +36,7 @@ #include #include "openair2/LAYER2/NR_MAC_UE/mac_defs.h" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" +#include "openair2/RRC/NR_UE/rrc_proto.h" #define TELNETSERVERCODE #include "telnetsrv.h" @@ -73,9 +74,20 @@ int get_sync_state(char *buf, int debug, telnet_printfunc_t prnt) return 0; } +/** + * Force RLF on UE + */ +int force_rlf(char *buf, int debug, telnet_printfunc_t prnt) +{ + NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(0); + handle_rlf_detection(rrc); + return 0; +} + /* Telnet shell command definitions */ static telnetshell_cmddef_t cicmds[] = { {"sync_state", "[UE_ID(int,opt)]", get_sync_state}, + {"force_rlf", "", force_rlf}, {"", "", NULL}, }; From 813690ece7b5b58a2cefe0935f06df3481c9dcc7 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jul 2024 17:51:38 +0200 Subject: [PATCH 13/19] Add ciUE command to force RRC_IDLE --- common/utils/telnetsrv/telnetsrv_ciUE.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/common/utils/telnetsrv/telnetsrv_ciUE.c b/common/utils/telnetsrv/telnetsrv_ciUE.c index 4cecd23272..dd95f8009c 100644 --- a/common/utils/telnetsrv/telnetsrv_ciUE.c +++ b/common/utils/telnetsrv/telnetsrv_ciUE.c @@ -84,10 +84,21 @@ int force_rlf(char *buf, int debug, telnet_printfunc_t prnt) return 0; } +/** + * Send UE to RRC_IDLE + */ +int force_RRC_IDLE(char *buf, int debug, telnet_printfunc_t prnt) +{ + NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(0); + nr_rrc_going_to_IDLE(rrc, OTHER, NULL); + return 0; +} + /* Telnet shell command definitions */ static telnetshell_cmddef_t cicmds[] = { {"sync_state", "[UE_ID(int,opt)]", get_sync_state}, {"force_rlf", "", force_rlf}, + {"force_RRC_IDLE", "", force_RRC_IDLE}, {"", "", NULL}, }; From 4f969e41209d0469a2d6a4d334fd0bbf0588be40 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 26 Jul 2024 17:55:39 +0200 Subject: [PATCH 14/19] do not force initial sync BW scanning if going to IDLE, keep the previous configuration --- executables/nr-ue.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index bd64a9d361..d6c3086317 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -607,7 +607,13 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc if (UE->synch_request.received_synch_request == 1) { fapi_nr_synch_request_t *synch_req = &UE->synch_request.synch_req; UE->is_synchronized = 0; - UE->UE_scan_carrier = synch_req->ssb_bw_scan; + // if upper layers signal BW scan we do as instructed by command line parameter + // if upper layers disable BW scan we set it to false + if (UE->synch_request.synch_req.ssb_bw_scan) + UE->UE_scan_carrier = get_nrUE_params()->UE_scan_carrier; + else + UE->UE_scan_carrier = false; + UE->target_Nid_cell = UE->synch_request.synch_req.target_Nid_cell; UE->target_Nid_cell = synch_req->target_Nid_cell; uint64_t dl_bw = (12 * fp->N_RB_DL) * (15000 << fp->numerology_index); From 5bb38187f193b876a775b933da93f8c20b8210b8 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 29 Jul 2024 15:11:28 +0200 Subject: [PATCH 15/19] triggering SR only if schedulingRequestResource is available --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 26b2f35e0f..a3be440cc7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1428,13 +1428,16 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac) // if the UL-SCH resources available for a new transmission do not meet the LCP mapping restrictions // TODO not implemented + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL; + if (!pucch_Config || !pucch_Config->schedulingRequestResourceToAddModList) + return; // cannot schedule SR if there is no schedulingRequestResource configured + if (lc_info->sr_id < 0 || lc_info->sr_id >= NR_MAX_SR_ID) LOG_E(NR_MAC, "No SR corresponding to this LCID\n"); // TODO not sure what to do here else { nr_sr_info_t *sr = &sched_info->sr_info[lc_info->sr_id]; if (!sr->pending) { - NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; - NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL; if (check_pucchres_for_pending_SR(pucch_Config, lc_info->sr_id)) { // trigger SR LOG_D(NR_MAC, "Triggering SR for ID %d\n", lc_info->sr_id); From fe671a887644e8e8379fdecbfb9055002834a7ee Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 29 Jul 2024 18:23:10 +0200 Subject: [PATCH 16/19] take into account the option to have initial pucch when scheduling UCI on PUSCH --- openair1/PHY/impl_defs_nr.h | 10 ---- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 9 +++ openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 10 +++- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 62 ++++++++++++-------- 5 files changed, 54 insertions(+), 39 deletions(-) diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 7f9dfad719..16d5854604 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -487,16 +487,6 @@ typedef enum { reserved = 7 } PUCCH_MaxCodeRate_t; -typedef struct { - pucch_format_nr_t format; - uint8_t startingSymbolIndex; - uint8_t nrofSymbols; - uint16_t PRB_offset; - uint8_t nb_CS_indexes; - uint8_t initial_CS_indexes[MAX_NB_CYCLIC_SHIFT]; -} initial_pucch_resource_t; - - /*********************************************************************** * * FUNCTIONALITY : Scheduling Request Configuration (SR) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 426d8f88d1..819cbea02f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -184,6 +184,15 @@ typedef enum { #undef UE_STATE } NR_UE_L2_STATE_t; +typedef struct { + pucch_format_nr_t format; + uint8_t startingSymbolIndex; + uint8_t nrofSymbols; + uint16_t PRB_offset; + uint8_t nb_CS_indexes; + uint8_t initial_CS_indexes[MAX_NB_CYCLIC_SHIFT]; +} initial_pucch_resource_t; + typedef enum { GO_TO_IDLE, DETACH, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6feca8756e..c5334ed04a 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -210,7 +210,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, int slot); bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch); - +initial_pucch_resource_t get_initial_pucch_resource(const int idx); void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int num_res); int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index bd233f2163..b853df90eb 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1514,6 +1514,11 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, current_harq->dai_cumul); } +initial_pucch_resource_t get_initial_pucch_resource(const int idx) +{ + return initial_pucch_resource[idx]; +} + int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame, @@ -1534,10 +1539,9 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource); // configure pucch from Table 9.2.1-1 // only for ack/nack - if (pucch->initial_pucch_id > -1 && - pucch->pucch_resource == NULL) { + if (pucch->initial_pucch_id > -1 && pucch->pucch_resource == NULL) { const int idx = *current_UL_BWP->pucch_ConfigCommon->pucch_ResourceCommon; - const initial_pucch_resource_t pucch_resourcecommon = initial_pucch_resource[idx]; + const initial_pucch_resource_t pucch_resourcecommon = get_initial_pucch_resource(idx); pucch_pdu->format_type = pucch_resourcecommon.format; pucch_pdu->start_symbol_index = pucch_resourcecommon.startingSymbolIndex; pucch_pdu->nr_of_symbols = pucch_resourcecommon.nrofSymbols; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index a3be440cc7..d1d523a962 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2322,7 +2322,11 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) LOG_D(NR_MAC,"Map SSB to RO done\n"); } -static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, const PUCCH_sched_t *pucch) +static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, + frame_t frame_tx, + int slot_tx, + const PUCCH_sched_t *pucch, + NR_UE_UL_BWP_t *current_UL_BWP) { fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = lockGet_ul_iterator(mac, frame_tx, slot_tx); if (!ulcfg_pdu) @@ -2337,29 +2341,37 @@ static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int s NR_PUCCH_Resource_t *pucchres = pucch->pucch_resource; int nr_of_symbols = 0; int start_symbol_index = 0; - switch(pucchres->format.present) { - case NR_PUCCH_Resource__format_PR_format0 : - nr_of_symbols = pucchres->format.choice.format0->nrofSymbols; - start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex; - break; - case NR_PUCCH_Resource__format_PR_format1 : - nr_of_symbols = pucchres->format.choice.format1->nrofSymbols; - start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex; - break; - case NR_PUCCH_Resource__format_PR_format2 : - nr_of_symbols = pucchres->format.choice.format2->nrofSymbols; - start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex; - break; - case NR_PUCCH_Resource__format_PR_format3 : - nr_of_symbols = pucchres->format.choice.format3->nrofSymbols; - start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex; - break; - case NR_PUCCH_Resource__format_PR_format4 : - nr_of_symbols = pucchres->format.choice.format4->nrofSymbols; - start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex; - break; - default : - AssertFatal(false, "Undefined PUCCH format \n"); + if (pucch->initial_pucch_id > -1 && pucch->pucch_resource == NULL) { + const int idx = *current_UL_BWP->pucch_ConfigCommon->pucch_ResourceCommon; + const initial_pucch_resource_t pucch_resourcecommon = get_initial_pucch_resource(idx); + start_symbol_index = pucch_resourcecommon.startingSymbolIndex; + nr_of_symbols = pucch_resourcecommon.nrofSymbols; + } + else { + switch(pucchres->format.present) { + case NR_PUCCH_Resource__format_PR_format0 : + nr_of_symbols = pucchres->format.choice.format0->nrofSymbols; + start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format1 : + nr_of_symbols = pucchres->format.choice.format1->nrofSymbols; + start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format2 : + nr_of_symbols = pucchres->format.choice.format2->nrofSymbols; + start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format3 : + nr_of_symbols = pucchres->format.choice.format3->nrofSymbols; + start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format4 : + nr_of_symbols = pucchres->format.choice.format4->nrofSymbols; + start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex; + break; + default : + AssertFatal(false, "Undefined PUCCH format \n"); + } } int final_symbol = nr_of_symbols + start_symbol_index; // PUCCH overlapping in time with PUSCH @@ -2468,7 +2480,7 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP) mac->nr_ue_emul_l1.num_csi_reports = pucch[j].n_csi; // checking if we need to schedule pucch[j] on PUSCH - if (schedule_uci_on_pusch(mac, frameP, slotP, &pucch[j])) + if (schedule_uci_on_pusch(mac, frameP, slotP, &pucch[j], mac->current_UL_BWP)) continue; fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH); From 6600e33caefb705caa28764fce26fa5383b5e80c Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 7 Oct 2024 16:39:07 +0200 Subject: [PATCH 17/19] workaround to avoid assertion for UCI on PUSCH in re-establishment procedure --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 33 +++++++++++---------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index d1d523a962..3836291d61 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2402,22 +2402,25 @@ static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, // and does not transmit the PUCCH if the UE does not multiplex aperiodic or semi-persistent CSI reports in the PUSCH bool mux_done = false; if (pucch->n_harq > 0) { - pusch_pdu->pusch_uci.harq_ack_bit_length = pucch->n_harq; - pusch_pdu->pusch_uci.harq_payload = pucch->ack_payload; NR_PUSCH_Config_t *pusch_Config = mac->current_UL_BWP->pusch_Config; - AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH, "UCI on PUSCH need to be configured\n"); - NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup; - AssertFatal(onPusch && - onPusch->betaOffsets && - onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic, - "Only semistatic beta offset is supported\n"); - NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic; - pusch_pdu->pusch_uci.beta_offset_harq_ack = pucch->n_harq > 2 ? - (pucch->n_harq < 12 ? *beta_offsets->betaOffsetACK_Index2 : - *beta_offsets->betaOffsetACK_Index3) : - *beta_offsets->betaOffsetACK_Index1; - pusch_pdu->pusch_uci.alpha_scaling = onPusch->scaling; - mux_done = true; + if (pusch_Config && pusch_Config->uci_OnPUSCH) { + NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup; + AssertFatal(onPusch && + onPusch->betaOffsets && + onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic, + "Only semistatic beta offset is supported\n"); + NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic; + pusch_pdu->pusch_uci.harq_ack_bit_length = pucch->n_harq; + pusch_pdu->pusch_uci.harq_payload = pucch->ack_payload; + pusch_pdu->pusch_uci.beta_offset_harq_ack = pucch->n_harq > 2 ? + (pucch->n_harq < 12 ? *beta_offsets->betaOffsetACK_Index2 : + *beta_offsets->betaOffsetACK_Index3) : + *beta_offsets->betaOffsetACK_Index1; + pusch_pdu->pusch_uci.alpha_scaling = onPusch->scaling; + mux_done = true; + } else { + LOG_E(NR_MAC, "UCI on PUSCH need to be configured to schedule UCI on PUSCH\n"); + } } if (pusch_pdu->pusch_uci.csi_part1_bit_length == 0 && pusch_pdu->pusch_uci.csi_part2_bit_length == 0) { // To support this we would need to shift some bits into CSI part2 -> need to change the logic From 4f2fa739a12bc7540030bbef4b2ae0497e07624a Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 9 Oct 2024 11:11:38 +0200 Subject: [PATCH 18/19] Disable ASAN ODR detection to workaround double registration of log_mem_write_side variable in CU /opt/oai-gnb/bin/nr-softmodem -O /opt/oai-gnb/etc/gnb.conf --sa --log_config.global_log_options level,nocolor,time --rfsimulator.options chanmod --telnetsrv --telnetsrv.listenaddr 192.168.71.150 --telnetsrv.shrmod ci ================================================================= ==7==ERROR: AddressSanitizer: odr-violation (0x7fce78b85be0): [1] size=4 'log_mem_write_side' /oai-ran/common/utils/LOG/log.c:78:14 [2] size=4 'log_mem_write_side' /oai-ran/common/utils/LOG/log.c:78:14 These globals were registered at these points: [1]: \#0 0x7fce7b691658 in __asan_register_globals ../../../../src/libsanitizer/asan/asan_globals.cpp:341 \#1 0x7fce7bd0c47d in call_init elf/dl-init.c:70 [2]: \#0 0x7fce7b691658 in __asan_register_globals ../../../../src/libsanitizer/asan/asan_globals.cpp:341 \#1 0x7fce7a5e2eba in call_init ../csu/libc-start.c:145 \#2 0x7fce7a5e2eba in __libc_start_main_impl ../csu/libc-start.c:379 ==7==HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_odr_violation=0 SUMMARY: AddressSanitizer: odr-violation: global 'log_mem_write_side' at /oai-ran/common/utils/LOG/log.c:78:14 ==7==ABORTING [INFO tini (1)] Spawned child process '/opt/oai-gnb/bin/entrypoint.sh' with pid '7' [INFO tini (1)] Main child exited normally (with status '1') --- ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index 4460452f11..df0a9f4b07 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -92,7 +92,7 @@ services: --rfsimulator.options chanmod --telnetsrv --telnetsrv.listenaddr 192.168.71.150 --telnetsrv.shrmod ci - ASAN_OPTIONS: detect_leaks=0 + ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 depends_on: - oai-ext-dn networks: From 6b3f26f538f4f3d99733ca43cef1ecb942ca857c Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 16 Oct 2024 16:31:03 +0200 Subject: [PATCH 19/19] Add define to printf and fflush in telnetsrv for real-time logs --- common/utils/telnetsrv/telnetsrv.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 43208748d0..9e708efc38 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -67,6 +67,12 @@ static telnetsrv_params_t telnetparams; #define TELNETSRV_OPTNAME_STATICMOD "staticmod" #define TELNETSRV_OPTNAME_SHRMOD "shrmod" +#define TELNET_LOG(fmt, ...) \ + do { \ + printf("[TELNETSRV] " fmt __VA_OPT__(, ) __VA_ARGS__); \ + fflush(stdout); \ + } while (0) + // clang-format off paramdef_t telnetoptions[] = { /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -653,10 +659,10 @@ void run_telnetsrv(void) { using_history(); int plen=sprintf(prompt,"%s_%s> ",TELNET_PROMPT_PREFIX,get_softmodem_function(NULL)); - printf("\nInitializing telnet server...\n"); + TELNET_LOG("\nInitializing telnet server...\n"); while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) { - printf("[TELNETSRV] Telnet client connected....\n"); + TELNET_LOG("Telnet client connected....\n"); read_history(telnetparams.histfile); stifle_history(telnetparams.histsize); @@ -682,12 +688,12 @@ void run_telnetsrv(void) { } if(!readc) { - printf ("[TELNETSRV] Telnet Client disconnected.\n"); + TELNET_LOG("Telnet Client disconnected.\n"); break; } if (telnetparams.telnetdbg > 0) - printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled,buf); + TELNET_LOG("Command received: readc %i filled %i \"%s\"\n", readc, filled, buf); if (buf[0] == '!') { if (buf[1] == '!') { @@ -720,7 +726,7 @@ void run_telnetsrv(void) { send(telnetparams.new_socket, prompt, strlen(prompt), MSG_NOSIGNAL); } else { - printf ("[TELNETSRV] Closing telnet connection...\n"); + TELNET_LOG("Closing telnet connection...\n"); break; } } @@ -728,7 +734,7 @@ void run_telnetsrv(void) { write_history(telnetparams.histfile); clear_history(); close(telnetparams.new_socket); - printf ("[TELNETSRV] Telnet server waitting for connection...\n"); + TELNET_LOG("Telnet server waiting for connection...\n"); } close(sock); @@ -927,7 +933,7 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde cmd[j].qptr = afifo; } } - printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n", i, telnetparams.CmdParsers[i].module); + TELNET_LOG("Telnet server: module %i = %s added to shell\n", i, telnetparams.CmdParsers[i].module); break; } }