Commit 004403c8 authored by Robert Schmidt's avatar Robert Schmidt

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: default avatarbatuhanduyuler <batuhan.duyuler@firecell.io>
Co-authored-by: default avatarrmagueta <rmagueta@allbesmart.pt>
parent d70561d5
......@@ -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 {
......
......@@ -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 */
......
......@@ -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,
......
......@@ -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);
}
}
}
......
......@@ -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,
......
......@@ -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 */
......
......@@ -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 {
......
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment