From 004403c84d57e8c0efb253e267b63a39b2cead63 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 23 May 2024 18:00:15 +0200 Subject: [PATCH] Implement F1 UE Ctxt Modif Transmission Action Indicator Implement the Transmission Action Indicator F1AP forwarding logic, and add it to the F1 internal representation structure. After the transmission interrupt timer (during which SRB1 can send messages), the UE will be out-of-sync (we assume it's not there anymore). Co-authored-by: batuhanduyuler Co-authored-by: rmagueta --- openair2/COMMON/f1ap_messages_types.h | 6 ++++++ openair2/F1AP/f1ap_cu_ue_context_management.c | 7 +++++-- openair2/F1AP/f1ap_du_ue_context_management.c | 15 +++++++++++++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 13 ++++++++++++- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 5 +++++ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 5 +++++ 8 files changed, 50 insertions(+), 4 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index f357fae2d8..569f3857c0 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -466,6 +466,11 @@ typedef enum ReconfigurationCompl_e { RRCreconf_success = 2, } ReconfigurationCompl_t; +typedef enum TransmActionInd_e { + TransmActionInd_STOP, + TransmActionInd_RESTART, +} TransmActionInd_t; + typedef struct f1ap_ue_context_setup_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; @@ -496,6 +501,7 @@ typedef struct f1ap_ue_context_setup_s { ReconfigurationCompl_t ReconfigComplOutcome; uint8_t *rrc_container; int rrc_container_length; + TransmActionInd_t *transm_action_ind; } f1ap_ue_context_setup_t, f1ap_ue_context_modif_req_t, f1ap_ue_context_modif_resp_t; typedef enum F1ap_Cause_e { diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index ca6c939a3a..924c9ecfca 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -1023,12 +1023,15 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte /* optional */ /* c7. TransmissionActionIndicator */ - if (0) { + if (f1ap_ue_context_modification_req->transm_action_ind != NULL) { asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie7); ie7->id = F1AP_ProtocolIE_ID_id_TransmissionActionIndicator; ie7->criticality = F1AP_Criticality_ignore; ie7->value.present = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator; - ie7->value.choice.TransmissionActionIndicator = F1AP_TransmissionActionIndicator_stop; + ie7->value.choice.TransmissionActionIndicator = *f1ap_ue_context_modification_req->transm_action_ind; + // Stop is guaranteed to be 0, by restart might be different from 1 + static_assert((int)F1AP_TransmissionActionIndicator_restart == (int)TransmActionInd_RESTART, + "mismatch of ASN.1 and internal representation\n"); } /* optional */ diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 8844e79baf..18a04962ad 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -911,6 +911,21 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieSrb, container, F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List, false); + F1AP_UEContextModificationRequestIEs_t *ieTxInd; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, + ieTxInd, + container, + F1AP_ProtocolIE_ID_id_TransmissionActionIndicator, + false); + + if (ieTxInd != NULL) { + f1ap_ue_context_modification_req->transm_action_ind = calloc_or_fail(1, sizeof(*f1ap_ue_context_modification_req->transm_action_ind)); + *f1ap_ue_context_modification_req->transm_action_ind = ieTxInd->value.choice.TransmissionActionIndicator; + // Stop is guaranteed to be 0, by restart might be different from 1 + static_assert((int)F1AP_TransmissionActionIndicator_restart == (int)TransmActionInd_RESTART, + "mismatch of ASN.1 and internal representation\n"); + } + if(ieSrb != NULL) { f1ap_ue_context_modification_req->srbs_to_be_setup_length = ieSrb->value.choice.SRBs_ToBeSetupMod_List.list.count; f1ap_ue_context_modification_req->srbs_to_be_setup = calloc(f1ap_ue_context_modification_req->srbs_to_be_setup_length, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index d860ec49bd..5ae2eb8607 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3017,6 +3017,14 @@ int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, interr return 0; } +int nr_transmission_action_indicator_stop(gNB_MAC_INST *mac, NR_UE_info_t *UE_info) +{ + int delay = nr_mac_get_reconfig_delay_slots(UE_info->current_DL_BWP.scs); + nr_mac_interrupt_ue_transmission(mac, UE_info, FOLLOW_OUTOFSYNC, delay); + LOG_I(NR_MAC, "gNB-DU received the TransmissionActionIndicator with Stop value for UE %04x\n", UE_info->rnti); + return 0; +} + void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int rnti) { // the CU might not know such UE, e.g., because we never sent a message to @@ -3078,7 +3086,10 @@ void nr_mac_update_timers(module_id_t module_id, if (nr_timer_tick(&sched_ctrl->transm_interrupt)) { /* expired */ nr_timer_stop(&sched_ctrl->transm_interrupt); - nr_mac_apply_cellgroup(mac, UE, frame, slot); + if (UE->interrupt_action == FOLLOW_OUTOFSYNC) + nr_mac_trigger_ul_failure(sched_ctrl, UE->current_DL_BWP.scs); + else + nr_mac_apply_cellgroup(mac, UE, frame, slot); } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index e63bbd8f99..4ee100f812 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -57,6 +57,7 @@ int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs); bool nr_mac_prepare_cellgroup_update(gNB_MAC_INST *nrmac, NR_UE_info_t *UE, NR_CellGroupConfig_t *CellGroup); int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, interrupt_followup_action_t action, int slots); +int nr_transmission_action_indicator_stop(gNB_MAC_INST *mac, NR_UE_info_t *UE_info); void clear_nr_nfapi_information(gNB_MAC_INST *gNB, int CC_idP, 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 33c0d5e33e..a69ab2732e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -588,6 +588,11 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) } else { ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, new_CellGroup); // we actually don't need it } + + if (req->transm_action_ind != NULL) { + AssertFatal(*req->transm_action_ind == TransmActionInd_STOP, "Transmission Action Indicator restart not handled yet\n"); + nr_transmission_action_indicator_stop(mac, UE); + } NR_SCHED_UNLOCK(&mac->sched_lock); /* some sanity checks, since we use the same type for request and response */ diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 8d97ddc607..e0cf53c5a0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -739,7 +739,7 @@ typedef struct nr_mac_rrc_ul_if_s { initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer; } nr_mac_rrc_ul_if_t; -typedef enum interrupt_followup_action { FOLLOW_INSYNC, FOLLOW_INSYNC_RECONFIG } interrupt_followup_action_t; +typedef enum interrupt_followup_action { FOLLOW_INSYNC, FOLLOW_INSYNC_RECONFIG, FOLLOW_OUTOFSYNC } interrupt_followup_action_t; /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ typedef struct { diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index a802e7ab4d..70d36a144f 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -168,6 +168,11 @@ static void ue_context_modification_request_f1ap(sctp_assoc_t assoc_id, const f1 f1ap_msg->rrc_container_length = req->rrc_container_length; memcpy(f1ap_msg->rrc_container, req->rrc_container, req->rrc_container_length); } + if (req->transm_action_ind != NULL) { + f1ap_msg->transm_action_ind = malloc(sizeof *f1ap_msg->transm_action_ind); + AssertFatal(f1ap_msg->transm_action_ind != NULL, "out of memory\n"); + *f1ap_msg->transm_action_ind = *req->transm_action_ind; + } itti_send_msg_to_task(TASK_CU_F1, 0, msg); }