From 6a0e636f00afb04c07e00955b2f647d92ea92706 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 4 Mar 2024 14:36:49 +0100 Subject: [PATCH] RAN Control cleanup - RAN Function Definition implemented - use mutual E2SM UE ID file - write_ctrl_rc_sm function cleanup --- openair2/E2AP/RAN_FUNCTION/CMakeLists.txt | 4 +- .../E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c | 545 +++++++++++++++--- 2 files changed, 465 insertions(+), 84 deletions(-) diff --git a/openair2/E2AP/RAN_FUNCTION/CMakeLists.txt b/openair2/E2AP/RAN_FUNCTION/CMakeLists.txt index 906a3d2c55..acada2c6dd 100644 --- a/openair2/E2AP/RAN_FUNCTION/CMakeLists.txt +++ b/openair2/E2AP/RAN_FUNCTION/CMakeLists.txt @@ -11,10 +11,9 @@ add_library(e2_ran_func_cuup STATIC O-RAN/ran_func_kpm_subs.c O-RAN/ran_func_rc.c # this file should only contain PDCP-U/GTP; to be done in the future O-RAN/ran_func_rc_subs.c - ../flexric/test/rnd/fill_rnd_data_rc.c # this dependancy will be taken out once RAN Function Definition is implemented ) -target_link_libraries(e2_ran_func_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj) +target_link_libraries(e2_ran_func_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj sm_common_ie_obj) target_compile_definitions(e2_ran_func_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_CUUP) @@ -31,7 +30,6 @@ add_library(e2_ran_func_du_cucp_cuup STATIC O-RAN/ran_func_rc.c # this file should only contain RRC/PDCP-C; to be done in the future # when nr-softmodem is divided in separate executables O-RAN/ran_func_rc_subs.c - ../flexric/test/rnd/fill_rnd_data_rc.c # this dependancy will be taken out once RAN Function Definition is implemented ../flexric/src/sm/rc_sm/ie/rc_data_ie.c CUSTOMIZED/ran_func_mac.c CUSTOMIZED/ran_func_rlc.c diff --git a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c index 7cf3e94f64..ef23bf2fd4 100644 --- a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c +++ b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c @@ -22,7 +22,7 @@ #include "ran_func_rc.h" #include "ran_func_rc_subs.h" #include "ran_func_rc_extern.h" -#include "../../flexric/test/rnd/fill_rnd_data_rc.h" // this dependancy will be taken out once RAN Function Definition is implemented +#include "ran_e2sm_ue_id.h" #include "../../flexric/src/sm/rc_sm/ie/ir/lst_ran_param.h" #include "../../flexric/src/sm/rc_sm/ie/ir/ran_param_list.h" #include "../../flexric/src/agent/e2_agent_api.h" @@ -35,17 +35,440 @@ static pthread_once_t once_rc_mutex = PTHREAD_ONCE_INIT; static rc_subs_data_t rc_subs_data = {0}; static pthread_mutex_t rc_mutex = PTHREAD_MUTEX_INITIALIZER; +static ngran_node_t get_e2_node_type(void) +{ + ngran_node_t node_type = 0; + +#if defined(NGRAN_GNB_DU) && defined(NGRAN_GNB_CUUP) && defined(NGRAN_GNB_CUCP) + node_type = RC.nrrrc[0]->node_type; +#elif defined (NGRAN_GNB_CUUP) + node_type = ngran_gNB_CUUP; +#endif + + return node_type; +} + static void init_once_rc(void) { init_rc_subs_data(&rc_subs_data); } +static void fill_rc_ev_trig(ran_func_def_ev_trig_t* ev_trig) +{ + // Sequence of EVENT TRIGGER styles + // [1 - 63] + ev_trig->sz_seq_ev_trg_style = 1; + ev_trig->seq_ev_trg_style = calloc(ev_trig->sz_seq_ev_trg_style, sizeof(seq_ev_trg_style_t)); + assert(ev_trig->seq_ev_trg_style != NULL && "Memory exhausted"); + + seq_ev_trg_style_t* ev_trig_style = &ev_trig->seq_ev_trg_style[0]; + + // RIC Event Trigger Style Type + // Mandatory + // 9.3.3 + // 6.2.2.2. + // INTEGER + ev_trig_style->style = 4; + + // RIC Event Trigger Style Name + // Mandatory + // 9.3.4 + // 6.2.2.3 + //PrintableString(SIZE(1..150,...)) + const char ev_style_name[] = "UE Information Change"; + ev_trig_style->name = cp_str_to_ba(ev_style_name); + + // RIC Event Trigger Format Type + // Mandatory + // 9.3.5 + // 6.2.2.4. + // INTEGER + ev_trig_style->format = FORMAT_4_E2SM_RC_EV_TRIGGER_FORMAT; + + // Sequence of RAN Parameters for L2 Variables + // [0 - 65535] + ev_trig->sz_seq_ran_param_l2_var = 0; + ev_trig->seq_ran_param_l2_var = NULL; + + //Sequence of Call Process Types + // [0-65535] + ev_trig->sz_seq_call_proc_type = 0; + ev_trig->seq_call_proc_type = NULL; + + // Sequence of RAN Parameters for Identifying UEs + // 0-65535 + ev_trig->sz_seq_ran_param_id_ue = 0; + ev_trig->seq_ran_param_id_ue = NULL; + + // Sequence of RAN Parameters for Identifying Cells + // 0-65535 + ev_trig->sz_seq_ran_param_id_cell = 0; + ev_trig->seq_ran_param_id_cell = NULL; +} + +static void fill_rc_report(ran_func_def_report_t* report) +{ + // Sequence of REPORT styles + // [1 - 63] + report->sz_seq_report_sty = 1; + report->seq_report_sty = calloc(report->sz_seq_report_sty, sizeof(seq_report_sty_t)); + assert(report->seq_report_sty != NULL && "Memory exhausted"); + + seq_report_sty_t* report_style = &report->seq_report_sty[0]; + + // RIC Report Style Type + // Mandatory + // 9.3.3 + // 6.2.2.2. + // INTEGER + report_style->report_type = 4; + + // RIC Report Style Name + // Mandatory + // 9.3.4 + // 6.2.2.3. + // PrintableString(SIZE(1..150,...)) + const char report_name[] = "UE Information"; + report_style->name = cp_str_to_ba(report_name); + + // Supported RIC Event Trigger Style Type + // Mandatory + // 9.3.3 + // 6.2.2.2. + // INTEGER + report_style->ev_trig_type = FORMAT_4_E2SM_RC_EV_TRIGGER_FORMAT; + + // RIC Report Action Format Type + // Mandatory + // 9.3.5 + // 6.2.2.4. + // INTEGER + report_style->act_frmt_type = FORMAT_1_E2SM_RC_ACT_DEF; + + // RIC Indication Header Format Type + // Mandatory + // 9.3.5 + // 6.2.2.4. + // INTEGER + report_style->ind_hdr_type = FORMAT_1_E2SM_RC_IND_HDR; + + // RIC Indication Message Format Type + // Mandatory + // 9.3.5 + // 6.2.2.4. + // INTEGER + report_style->ind_msg_type = FORMAT_2_E2SM_RC_IND_MSG; + + // Sequence of RAN Parameters Supported + // [0 - 65535] + report_style->sz_seq_ran_param = 1; + report_style->ran_param = calloc(report_style->sz_seq_ran_param, sizeof(seq_ran_param_3_t)); + assert(report_style->ran_param != NULL && "Memory exhausted"); + + // RAN Parameter ID + // Mandatory + // 9.3.8 + // [1- 4294967295] + report_style->ran_param[0].id = RRC_STATE_CHANGED_TO_E2SM_RC_RAN_PARAM_ID; + + // RAN Parameter Name + // Mandatory + // 9.3.9 + // [1-150] + const char ran_param_name[] = "RRC State"; + report_style->ran_param[0].name = cp_str_to_ba(ran_param_name); + + // RAN Parameter Definition + // Optional + // 9.3.51 + report_style->ran_param[0].def = NULL; +} + +static void fill_rc_control(ran_func_def_ctrl_t* ctrl) +{ + // Sequence of CONTROL styles + // [1 - 63] + ctrl->sz_seq_ctrl_style = 1; + ctrl->seq_ctrl_style = calloc(ctrl->sz_seq_ctrl_style, sizeof(seq_ctrl_style_t)); + assert(ctrl->seq_ctrl_style != NULL && "Memory exhausted"); + + seq_ctrl_style_t* ctrl_style = &ctrl->seq_ctrl_style[0]; + + // RIC Control Style Type + // Mandatory + // 9.3.3 + // 6.2.2.2 + ctrl_style->style_type = 1; + + //RIC Control Style Name + //Mandatory + //9.3.4 + // [1 -150] + const char control_name[] = "Radio Bearer Control"; + ctrl_style->name = cp_str_to_ba(control_name); + + // RIC Control Header Format Type + // Mandatory + // 9.3.5 + ctrl_style->hdr = FORMAT_1_E2SM_RC_CTRL_HDR; + + // RIC Control Message Format Type + // Mandatory + // 9.3.5 + ctrl_style->msg = FORMAT_1_E2SM_RC_CTRL_MSG; + + // RIC Call Process ID Format Type + // Optional + ctrl_style->call_proc_id_type = NULL; + + // RIC Control Outcome Format Type + // Mandatory + // 9.3.5 + ctrl_style->out_frmt = FORMAT_1_E2SM_RC_CTRL_OUT; + + // Sequence of Control Actions + // [0-65535] + ctrl_style->sz_seq_ctrl_act = 1; + ctrl_style->seq_ctrl_act = calloc(ctrl_style->sz_seq_ctrl_act, sizeof(seq_ctrl_act_2_t)); + assert(ctrl_style->seq_ctrl_act != NULL && "Memory exhausted"); + + seq_ctrl_act_2_t* ctrl_act = &ctrl_style->seq_ctrl_act[0]; + + // Control Action ID + // Mandatory + // 9.3.6 + // [1-65535] + ctrl_act->id = 2; + + // Control Action Name + // Mandatory + // 9.3.7 + // [1-150] + const char control_act_name[] = "QoS flow mapping configuration"; + ctrl_act->name = cp_str_to_ba(control_act_name); + + // Sequence of Associated RAN Parameters + // [0-65535] + ctrl_act->sz_seq_assoc_ran_param = 2; + ctrl_act->assoc_ran_param = calloc(ctrl_act->sz_seq_assoc_ran_param, sizeof(seq_ran_param_3_t)); + assert(ctrl_act->assoc_ran_param != NULL && "Memory exhausted"); + + seq_ran_param_3_t* assoc_ran_param = ctrl_act->assoc_ran_param; + + // DRB ID + assoc_ran_param[0].id = 1; + const char ran_param_drb_id[] = "DRB ID"; + assoc_ran_param[0].name = cp_str_to_ba(ran_param_drb_id); + assoc_ran_param[0].def = NULL; + + // List of QoS Flows to be modified in DRB + assoc_ran_param[1].id = 2; + const char ran_param_list_qos_flow[] = "List of QoS Flows to be modified in DRB"; + assoc_ran_param[1].name = cp_str_to_ba(ran_param_list_qos_flow); + assoc_ran_param[1].def = calloc(1, sizeof(ran_param_def_t)); + assert(assoc_ran_param[1].def != NULL && "Memory exhausted"); + + assoc_ran_param[1].def->type = LIST_RAN_PARAMETER_DEF_TYPE; + assoc_ran_param[1].def->lst = calloc(1, sizeof(ran_param_type_t)); + assert(assoc_ran_param[1].def->lst != NULL && "Memory exhausted"); + + ran_param_type_t* lst = assoc_ran_param[1].def->lst; + lst->sz_ran_param = 2; + lst->ran_param = calloc(lst->sz_ran_param, sizeof(ran_param_lst_struct_t)); + assert(lst->ran_param != NULL && "Memory exhausted"); + + // QoS Flow Identifier + lst->ran_param[0].ran_param_id = 4; + const char ran_param_qos_flow_id[] = "QoS Flow Identifier"; + lst->ran_param[0].ran_param_name = cp_str_to_ba(ran_param_qos_flow_id); + lst->ran_param[0].ran_param_def = NULL; + + // QoS Flow Mapping Indication + lst->ran_param[1].ran_param_id = 5; + const char ran_param_qos_flow_mapping_ind[] = "QoS Flow Mapping Indication"; + lst->ran_param[1].ran_param_name = cp_str_to_ba(ran_param_qos_flow_mapping_ind); + lst->ran_param[1].ran_param_def = NULL; + + // Sequence of Associated RAN + // Parameters for Control Outcome + // [0- 255] + ctrl_style->sz_ran_param_ctrl_out = 0; + ctrl_style->ran_param_ctrl_out = NULL; +} + +e2sm_rc_func_def_t fill_rc_ran_def_gnb(void) +{ + e2sm_rc_func_def_t def = {0}; + + // RAN Function Definition for EVENT TRIGGER + // Optional + // 9.2.2.2 + def.ev_trig = calloc(1, sizeof(ran_func_def_ev_trig_t)); + assert(def.ev_trig != NULL && "Memory exhausted"); + fill_rc_ev_trig(def.ev_trig); + + // RAN Function Definition for REPORT + // Optional + // 9.2.2.3 + def.report = calloc(1, sizeof(ran_func_def_report_t)); + assert(def.report != NULL && "Memory exhausted"); + fill_rc_report(def.report); + + // RAN Function Definition for INSERT + // Optional + // 9.2.2.4 + def.insert = NULL; + + // RAN Function Definition for CONTROL + // Optional + // 9.2.2.5 + def.ctrl = calloc(1, sizeof(ran_func_def_ctrl_t)); + assert(def.ctrl != NULL && "Memory exhausted"); + fill_rc_control(def.ctrl); + + // RAN Function Definition for POLICY + // Optional + // 9.2.2.6 + def.policy = NULL; + + return def; +} + +static e2sm_rc_func_def_t fill_rc_ran_def_cu(void) +{ + e2sm_rc_func_def_t def = {0}; + + // RAN Function Definition for EVENT TRIGGER + // Optional + // 9.2.2.2 + def.ev_trig = calloc(1, sizeof(ran_func_def_ev_trig_t)); + assert(def.ev_trig != NULL && "Memory exhausted"); + fill_rc_ev_trig(def.ev_trig); + + // RAN Function Definition for REPORT + // Optional + // 9.2.2.3 + def.report = calloc(1, sizeof(ran_func_def_report_t)); + assert(def.report != NULL && "Memory exhausted"); + fill_rc_report(def.report); + + // RAN Function Definition for INSERT + // Optional + // 9.2.2.4 + def.insert = NULL; + + // RAN Function Definition for CONTROL + // Optional + // 9.2.2.5 + def.ctrl = calloc(1, sizeof(ran_func_def_ctrl_t)); + assert(def.ctrl != NULL && "Memory exhausted"); + fill_rc_control(def.ctrl); + + // RAN Function Definition for POLICY + // Optional + // 9.2.2.6 + def.policy = NULL; + + return def; +} + +static e2sm_rc_func_def_t fill_rc_ran_def_null(void) +{ + e2sm_rc_func_def_t def = {0}; + + // RAN Function Definition for EVENT TRIGGER + // Optional + // 9.2.2.2 + def.ev_trig = NULL; + + // RAN Function Definition for REPORT + // Optional + // 9.2.2.3 + def.report = NULL; + + // RAN Function Definition for INSERT + // Optional + // 9.2.2.4 + def.insert = NULL; + + // RAN Function Definition for CONTROL + // Optional + // 9.2.2.5 + def.ctrl = NULL; + + // RAN Function Definition for POLICY + // Optional + // 9.2.2.6 + def.policy = NULL; + + return def; +} + +static e2sm_rc_func_def_t fill_rc_ran_def_cucp(void) +{ + e2sm_rc_func_def_t def = {0}; + + // RAN Function Definition for EVENT TRIGGER + // Optional + // 9.2.2.2 + def.ev_trig = calloc(1, sizeof(ran_func_def_ev_trig_t)); + assert(def.ev_trig != NULL && "Memory exhausted"); + fill_rc_ev_trig(def.ev_trig); + + // RAN Function Definition for REPORT + // Optional + // 9.2.2.3 + def.report = calloc(1, sizeof(ran_func_def_report_t)); + assert(def.report != NULL && "Memory exhausted"); + fill_rc_report(def.report); + + // RAN Function Definition for INSERT + // Optional + // 9.2.2.4 + def.insert = NULL; + + // RAN Function Definition for CONTROL + // Optional + // 9.2.2.5 + def.ctrl = NULL; + + // RAN Function Definition for POLICY + // Optional + // 9.2.2.6 + def.policy = NULL; + + return def; +} + +typedef e2sm_rc_func_def_t (*fp_rc_func_def)(void); + +static const fp_rc_func_def ran_def_rc[END_NGRAN_NODE_TYPE] = +{ + NULL, + NULL, + fill_rc_ran_def_gnb, + NULL, + NULL, + fill_rc_ran_def_cu, + NULL, + fill_rc_ran_def_null, // DU - at the moment, no Service is supported + NULL, + fill_rc_ran_def_cucp, + fill_rc_ran_def_null, // CU-UP - at the moment, no Service is supported +}; + void read_rc_setup_sm(void* data) { assert(data != NULL); // assert(data->type == RAN_CTRL_V1_3_AGENT_IF_E2_SETUP_ANS_V0); rc_e2_setup_t* rc = (rc_e2_setup_t*)data; - rc->ran_func_def = fill_rc_ran_func_def(); + + /* Fill the RAN Function Definition with currently supported measurements */ + + // RAN Function Name is already filled in fill_ran_function_name() in rc_sm_agent.c + + const ngran_node_t node_type = get_e2_node_type(); + rc->ran_func_def = ran_def_rc[node_type](); // E2 Setup Request is sent periodically until the connection is established // RC subscritpion data should be initialized only once @@ -56,53 +479,6 @@ void read_rc_setup_sm(void* data) RB_PROTOTYPE(ric_id_2_param_id_trees, ric_req_id_s, entries, cmp_ric_req_id); -static ue_id_e2sm_t fill_ue_id_data(const gNB_RRC_UE_t *rrc_ue_context) -{ - ue_id_e2sm_t ue_id = {0}; - - // Check the E2 node type - #if defined (NGRAN_GNB_CUUP) && defined (NGRAN_GNB_CUCP) - ue_id.type = GNB_UE_ID_E2SM; - if (RC.nrrrc[0]->node_type == ngran_gNB_CU) { - // gNB-CU UE F1AP ID List - // C-ifCUDUseparated - ue_id.gnb.gnb_cu_ue_f1ap_lst_len = 1; - ue_id.gnb.gnb_cu_ue_f1ap_lst = calloc(ue_id.gnb.gnb_cu_ue_f1ap_lst_len, sizeof(uint32_t)); - assert(ue_id.gnb.gnb_cu_ue_f1ap_lst != NULL && "Memory exhausted"); - - for(size_t i = 0; i < ue_id.gnb.gnb_cu_ue_f1ap_lst_len; i++) { - ue_id.gnb.gnb_cu_ue_f1ap_lst[i] = rrc_ue_context->rrc_ue_id; - } - } else if (RC.nrrrc[0]->node_type == ngran_gNB_CUCP) { - //gNB-CU-CP UE E1AP ID List - //C-ifCPUPseparated - ue_id.gnb.gnb_cu_cp_ue_e1ap_lst_len = 1; - ue_id.gnb.gnb_cu_cp_ue_e1ap_lst = calloc(ue_id.gnb.gnb_cu_cp_ue_e1ap_lst_len, sizeof(uint32_t)); - assert(ue_id.gnb.gnb_cu_cp_ue_e1ap_lst != NULL && "Memory exhausted"); - - for(size_t i = 0; i < ue_id.gnb.gnb_cu_cp_ue_e1ap_lst_len; i++) { - ue_id.gnb.gnb_cu_cp_ue_e1ap_lst[i] = rrc_ue_context->rrc_ue_id; - } - } else if (RC.nrrrc[0]->node_type == ngran_gNB_DU) { - assert(false && "RRC state change cannot be triggered from DU\n"); - } - - #elif defined (NGRAN_GNB_CUUP) - assert(false && "RRC state change cannot be triggered from CU-UP\n"); - - #endif - - ue_id.gnb.amf_ue_ngap_id = rrc_ue_context->rrc_ue_id; - ue_id.gnb.guami.amf_ptr = rrc_ue_context->ue_guami.amf_pointer; - ue_id.gnb.guami.amf_region_id = rrc_ue_context->ue_guami.amf_region_id; - ue_id.gnb.guami.amf_set_id = rrc_ue_context->ue_guami.amf_set_id; - ue_id.gnb.guami.plmn_id.mcc = rrc_ue_context->ue_guami.mcc; - ue_id.gnb.guami.plmn_id.mnc = rrc_ue_context->ue_guami.mnc; - ue_id.gnb.guami.plmn_id.mnc_digit_len = rrc_ue_context->ue_guami.mnc_len; - - return ue_id; -} - static seq_ran_param_t fill_rrc_state_change_seq_ran(const rc_sm_rrc_state_e rrc_state) { seq_ran_param_t seq_ran_param = {0}; @@ -138,7 +514,8 @@ static rc_ind_data_t* fill_ue_rrc_state_change(const gNB_RRC_UE_t *rrc_ue_contex // UE ID // Mandatory // 9.3.10 - rc_ind->msg.frmt_2.seq_ue_id[0].ue_id = fill_ue_id_data(rrc_ue_context); + const ngran_node_t node_type = get_e2_node_type(); + rc_ind->msg.frmt_2.seq_ue_id[0].ue_id = fill_ue_id_data[node_type](rrc_ue_context, 0, 0); // Sequence of // RAN Parameter @@ -221,39 +598,45 @@ sm_ag_if_ans_t write_ctrl_rc_sm(void const* data) // assert(data->type == RAN_CONTROL_CTRL_V1_03 ); rc_ctrl_req_data_t const* ctrl = (rc_ctrl_req_data_t const*)data; - if(ctrl->hdr.format == FORMAT_1_E2SM_RC_CTRL_HDR){ - if(ctrl->hdr.frmt_1.ric_style_type == 1 && ctrl->hdr.frmt_1.ctrl_act_id == 2){ - printf("QoS flow mapping configuration \n"); - e2sm_rc_ctrl_msg_frmt_1_t const* frmt_1 = &ctrl->msg.frmt_1; - for(size_t i = 0; i < frmt_1->sz_ran_param; ++i){ - seq_ran_param_t const* rp = frmt_1->ran_param; - if(rp[i].ran_param_id == 1){ - assert(rp[i].ran_param_val.type == ELEMENT_KEY_FLAG_TRUE_RAN_PARAMETER_VAL_TYPE ); - printf("DRB ID %ld \n", rp[i].ran_param_val.flag_true->int_ran); - } else if(rp[i].ran_param_id == 2){ - assert(rp[i].ran_param_val.type == LIST_RAN_PARAMETER_VAL_TYPE); - printf("List of QoS Flows to be modified \n"); - for(size_t j = 0; j < ctrl->msg.frmt_1.ran_param[i].ran_param_val.lst->sz_lst_ran_param; ++j){ - lst_ran_param_t const* lrp = rp[i].ran_param_val.lst->lst_ran_param; - // The following assertion should be true, but there is a bug in the std - // check src/sm/rc_sm/enc/rc_enc_asn.c:1085 and src/sm/rc_sm/enc/rc_enc_asn.c:984 - // assert(lrp[j].ran_param_id == 3); - assert(lrp[j].ran_param_struct.ran_param_struct[0].ran_param_id == 4) ; - assert(lrp[j].ran_param_struct.ran_param_struct[0].ran_param_val.type == ELEMENT_KEY_FLAG_TRUE_RAN_PARAMETER_VAL_TYPE); - int64_t qfi = lrp[j].ran_param_struct.ran_param_struct[0].ran_param_val.flag_true->int_ran; - assert(qfi > -1 && qfi < 65); + assert(ctrl->hdr.format == FORMAT_1_E2SM_RC_CTRL_HDR && "Indication Header Format received not valid"); + assert(ctrl->msg.format == FORMAT_1_E2SM_RC_CTRL_MSG && "Indication Message Format received not valid"); + assert(ctrl->hdr.frmt_1.ctrl_act_id == 2 && "Currently only QoS flow mapping configuration supported"); + + printf("QoS flow mapping configuration\n"); + + const seq_ran_param_t* ran_param = ctrl->msg.frmt_1.ran_param; + + // DRB ID + assert(ran_param[0].ran_param_id == 1 && "First RAN Parameter ID has to be DRB ID"); + assert(ran_param[0].ran_param_val.type == ELEMENT_KEY_FLAG_TRUE_RAN_PARAMETER_VAL_TYPE); + printf("DRB ID %ld \n", ran_param[0].ran_param_val.flag_true->int_ran); + + + // List of QoS Flows to be modified in DRB + assert(ran_param[1].ran_param_id == 2 && "Second RAN Parameter ID has to be List of QoS Flows"); + assert(ran_param[1].ran_param_val.type == LIST_RAN_PARAMETER_VAL_TYPE); + printf("List of QoS Flows to be modified in DRB\n"); + const lst_ran_param_t* lrp = ran_param[1].ran_param_val.lst->lst_ran_param; + + // The following assertion should be true, but there is a bug in the std + // check src/sm/rc_sm/enc/rc_enc_asn.c:1085 and src/sm/rc_sm/enc/rc_enc_asn.c:984 + // assert(lrp->ran_param_struct.ran_param_struct[0].ran_param_id == 3); + + // QoS Flow Identifier + assert(lrp->ran_param_struct.ran_param_struct[0].ran_param_id == 4); + assert(lrp->ran_param_struct.ran_param_struct[0].ran_param_val.type == ELEMENT_KEY_FLAG_TRUE_RAN_PARAMETER_VAL_TYPE); + int64_t qfi = lrp->ran_param_struct.ran_param_struct[0].ran_param_val.flag_true->int_ran; + assert(qfi > -1 && qfi < 65); + + // QoS Flow Mapping Indication + assert(lrp->ran_param_struct.ran_param_struct[1].ran_param_id == 5); + assert(lrp->ran_param_struct.ran_param_struct[1].ran_param_val.type == ELEMENT_KEY_FLAG_FALSE_RAN_PARAMETER_VAL_TYPE); + int64_t dir = lrp->ran_param_struct.ran_param_struct[1].ran_param_val.flag_false->int_ran; + assert(dir == 0 || dir == 1); + + printf("qfi = %ld, dir %ld \n", qfi, dir); - assert(lrp[j].ran_param_struct.ran_param_struct[1].ran_param_id == 5); - assert(lrp[j].ran_param_struct.ran_param_struct[1].ran_param_val.type == ELEMENT_KEY_FLAG_FALSE_RAN_PARAMETER_VAL_TYPE); - int64_t dir = lrp[j].ran_param_struct.ran_param_struct[1].ran_param_val.flag_false->int_ran; - assert(dir == 0 || dir == 1); - printf("qfi = %ld dir %ld \n", qfi, dir); - } - } - } - } - } sm_ag_if_ans_t ans = {.type = CTRL_OUTCOME_SM_AG_IF_ANS_V0}; ans.ctrl_out.type = RAN_CTRL_V1_3_AGENT_IF_CTRL_ANS_V0;