diff --git a/examples/emulator/agent/CMakeLists.txt b/examples/emulator/agent/CMakeLists.txt index 051390211389112258b7dbd0f2b3e1b5d823deac..d6886ee896b99cf0c01ad29b3acd7dd3d18d339a 100644 --- a/examples/emulator/agent/CMakeLists.txt +++ b/examples/emulator/agent/CMakeLists.txt @@ -19,7 +19,6 @@ add_library(test_agent_obj OBJECT sm_gtp.c sm_mac.c sm_pdcp.c - sm_rc.c sm_rlc.c sm_slice.c sm_tc.c @@ -35,6 +34,7 @@ add_executable(emu_agent_gnb test_agent.c read_setup_ran.c sm_kpm.c + sm_rc.c $<TARGET_OBJECTS:test_agent_obj> ) @@ -64,6 +64,7 @@ add_executable(emu_agent_gnb_cu test_agent.c read_setup_ran.c sm_kpm.c + sm_rc.c $<TARGET_OBJECTS:test_agent_obj> ) @@ -93,6 +94,7 @@ add_executable(emu_agent_gnb_du test_agent.c read_setup_ran.c sm_kpm.c + sm_rc.c $<TARGET_OBJECTS:test_agent_obj> ) @@ -121,6 +123,7 @@ add_executable(emu_agent_enb test_agent.c read_setup_ran.c sm_kpm.c + sm_rc.c $<TARGET_OBJECTS:test_agent_obj> ) diff --git a/examples/emulator/agent/sm_kpm.c b/examples/emulator/agent/sm_kpm.c index 9378fb3fc50b45cbd0102ad2376c675540878b82..fac89a56bdc9b777f306b899e3df317a2d15ae4b 100644 --- a/examples/emulator/agent/sm_kpm.c +++ b/examples/emulator/agent/sm_kpm.c @@ -284,14 +284,16 @@ int dummy_cnt = 0; // Dummy function. It emulates a function where the UE fullfills (or not) // the condition static -bool ue_fullfills_predicate(test_cond_e cond, int64_t value) +bool ue_fullfills_predicate(test_cond_e cond, test_cond_value_t value) { assert(cond == EQUAL_TEST_COND || cond == GREATERTHAN_TEST_COND || cond == CONTAINS_TEST_COND || cond == PRESENT_TEST_COND ); - assert(value > -1 && "Assuming this for testing"); + + assert(value.type == OCTET_STRING_TEST_COND_VALUE && "Only for testing"); + assert(value.octet_string_value->buf[0] > -1 && "Assuming this for testing"); dummy_cnt++; if(dummy_cnt > 32 && dummy_cnt < 4*32){ @@ -312,7 +314,7 @@ seq_arr_t emulate_ues_fullfilling_pred(test_info_lst_t const* info) seq_init(&dst, sizeof(ue_id_e2sm_t)); // for(size_t i = 0; i < num_ues; ++i){ - bool const select_ue = ue_fullfills_predicate(*info->test_cond, *info->test_cond_value->int_value ); + bool const select_ue = ue_fullfills_predicate(*info->test_cond, *info->test_cond_value); if(select_ue){ ue_id_e2sm_t ue = fill_rnd_ue_id_data(); seq_push_back(&dst, &ue, sizeof(ue_id_e2sm_t)); @@ -418,7 +420,6 @@ seq_arr_t match_s_nssai_test_cond_type(test_info_lst_t const* info) { assert(info != NULL); assert(info->test_cond_type == S_NSSAI_TEST_COND_TYPE); - assert(info->test_cond_value->type == INTEGER_TEST_COND_VALUE); return emulate_ues_fullfilling_pred(info); } @@ -572,8 +573,9 @@ bool read_kpm_sm(void* data) return true; } +#if defined KPM_V2_03 || defined KPM_V3_00 static -ric_report_style_item_t fill_ric_report_style_item(void) +ric_report_style_item_t fill_kpm_report_style_4(void) { ric_report_style_item_t dst = {0}; @@ -638,6 +640,20 @@ ric_report_style_item_t fill_ric_report_style_item(void) return dst; } +#endif + +static +ric_event_trigger_style_item_t fill_kpm_ev_tr_style(void) +{ + ric_event_trigger_style_item_t ev_tr_item = {0}; + + ev_tr_item.style_type = STYLE_1_RIC_EVENT_TRIGGER; + const char ev_style_name[] = "Periodic Report"; + ev_tr_item.style_name = cp_str_to_ba(ev_style_name); + ev_tr_item.format_type = FORMAT_1_RIC_EVENT_TRIGGER; + + return ev_tr_item; +} static kpm_ran_function_def_t fill_kpm_ran_func_def(void) @@ -645,13 +661,22 @@ kpm_ran_function_def_t fill_kpm_ran_func_def(void) kpm_ran_function_def_t dst = {0}; // RAN Function name is already filled by the kpm_sm_agent.c - dst.sz_ric_event_trigger_style_list = 0; - dst.ric_event_trigger_style_list = 0; - dst.sz_ric_report_style_list = 1; - dst.ric_report_style_list = ecalloc(dst.sz_ric_report_style_list, sizeof(ric_report_style_item_t )); + // Sequence of Event Trigger styles + size_t const sz_ev_tr = 1; + dst.sz_ric_event_trigger_style_list = sz_ev_tr; + dst.ric_event_trigger_style_list = ecalloc(sz_ev_tr, sizeof(ric_event_trigger_style_item_t)); + + dst.ric_event_trigger_style_list[0] = fill_kpm_ev_tr_style(); + + // Sequence of Report styles +#if defined KPM_V2_03 || defined KPM_V3_00 + size_t const sz_report = 1; + dst.sz_ric_report_style_list = sz_report; + dst.ric_report_style_list = ecalloc(sz_report, sizeof(ric_report_style_item_t )); - dst.ric_report_style_list[0] = fill_ric_report_style_item(); + dst.ric_report_style_list[0] = fill_kpm_report_style_4(); +#endif return dst; } diff --git a/examples/emulator/agent/sm_rc.c b/examples/emulator/agent/sm_rc.c index 207aeb811fd481636792b8c22bf5f16bfbfa82bc..165a4ebd85554d36b93b88fcd52c5f9b0a204c01 100644 --- a/examples/emulator/agent/sm_rc.c +++ b/examples/emulator/agent/sm_rc.c @@ -18,7 +18,11 @@ void free_rc_sm(void) } +typedef enum { + RRC_STATE_CHANGED_TO_E2SM_RC_RAN_PARAM_ID = 202, // 8.2.4 RAN Parameters for Report Service Style 4 + END_E2SM_RC_RAN_PARAM_ID +} ran_param_id_e; bool read_rc_sm(void* data) { @@ -28,12 +32,322 @@ bool read_rc_sm(void* data) return true; } +#if defined(NGRAN_GNB) || defined(NGRAN_GNB_CU) +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 +seq_ran_param_3_t fill_rc_ran_param(void) +{ + seq_ran_param_3_t ran_param = {0}; + + // RAN Parameter ID + // Mandatory + // 9.3.8 + // [1- 4294967295] + ran_param.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"; + ran_param.name = cp_str_to_ba(ran_param_name); + + // RAN Parameter Definition + // Optional + // 9.3.51 + ran_param.def = NULL; + + return ran_param; +} + +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"); + report_style->ran_param[0] = fill_rc_ran_param(); +} + +static +seq_ctrl_act_2_t fill_rc_ctrl_act(void) +{ + seq_ctrl_act_2_t 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; + + return ctrl_act; +} + +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"); + ctrl_style->seq_ctrl_act[0] = fill_rc_ctrl_act(); + + // 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; +} +#endif + +static +e2sm_rc_func_def_t fill_rc_ran_def(void) +{ + e2sm_rc_func_def_t def = {0}; + +#if defined(NGRAN_GNB) || defined(NGRAN_GNB_CU) + // 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 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 INSERT + // Optional + // 9.2.2.4 + def.insert = NULL; + + // RAN Function Definition for POLICY + // Optional + // 9.2.2.6 + def.policy = NULL; +#endif + + return def; +} + 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 + + rc->ran_func_def = fill_rc_ran_def(); } sm_ag_if_ans_t write_ctrl_rc_sm(void const* data)