RAN Control REPORT Style 1: "UE ID" support
As per spec, UE ID shall be reported when the message event configured by the Event Trigger Style 1 is set to “RRC Setup Complete" message (UE attach), or “Xn/NG Handover Request” or “F1 UE Context Setup Request” (Intra gNB Handover). In OAI RAN, Xn/NG Handover is not yet supported, and therefore not added as the trigger event in this commit. Additionally, as the Event Trigger Definition Format 1 is common for both "RRC Message" and "UE ID", E2 node will report the “RRC Setup Complete" message which the xApp will decode and print. Co-authored-by: Khanh Toan Pham <khanh.toan.pham@hhi.fraunhofer.de> Co-authored-by: Shrinish Donde <shrinish.donde@hhi.fraunhofer.de> Co-authored-by: Theodoros Tsourdinis <theodoros.tsourdinis@sorbonne-universite.fr> Co-authored-by: Miguel Fuentes <miguel.fuentes@i2cat.net> Co-authored-by: Teodora Vladic <teodora.vladic@openairinterface.org>
This commit is contained in:
committed by
Robert Schmidt
co-authored by
Khanh Toan Pham
Shrinish Donde
Theodoros Tsourdinis
Miguel Fuentes
Teodora Vladic
parent
8477de3571
commit
c612005d28
@@ -453,6 +453,9 @@ target_include_directories(f1ap PUBLIC F1AP_DIR)
|
||||
target_link_libraries(f1ap PUBLIC asn1_f1ap GTPV1U)
|
||||
target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE f1ap_lib)
|
||||
target_include_directories(f1ap PRIVATE ${F1AP_DIR}/lib)
|
||||
if(E2_AGENT)
|
||||
target_compile_definitions(f1ap PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
# LPP
|
||||
##############
|
||||
|
||||
@@ -1,4 +1,44 @@
|
||||
set(UE_ID_COMMON_E2SM_SRCS
|
||||
../flexric/src/sm/rc_sm/ie/asn/AMFPointer.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/AMFRegionID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/AMFSetID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/AMF-UE-NGAP-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/ENB-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/ENB-UE-X2AP-ID-Extension.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/ENB-UE-X2AP-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/GlobalENB-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/GlobalGNB-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/GlobalNgENB-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/GlobalNGRANNodeID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/GNB-CU-CP-UE-E1AP-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/GNB-CU-UE-F1AP-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/GNB-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/GUAMI.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/GUMMEI.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/MME-Code.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/MME-Group-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/MME-UE-S1AP-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/NGENB-CU-UE-W1AP-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/NgENB-ID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/NG-RANnodeUEXnAPID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/PLMNIdentity.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/RANUEID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-ENB.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-EN-GNB.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-GNB-CU-CP-E1AP-ID-Item.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-GNB-CU-CP-E1AP-ID-List.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-GNB-CU-CP-F1AP-ID-Item.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-GNB-CU-F1AP-ID-List.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-GNB-CU-UP.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-GNB-DU.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-GNB.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-NG-ENB-DU.c
|
||||
../flexric/src/sm/rc_sm/ie/asn/UEID-NG-ENB.c
|
||||
)
|
||||
|
||||
add_library(e2_ran_func_cuup STATIC
|
||||
${UE_ID_COMMON_E2SM_SRCS}
|
||||
init_ran_func.c
|
||||
read_setup_ran.c
|
||||
O-RAN/ran_e2sm_ue_id.c
|
||||
@@ -13,11 +53,12 @@ add_library(e2_ran_func_cuup STATIC
|
||||
../flexric/test/rnd/fill_rnd_data_tc.c
|
||||
)
|
||||
|
||||
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 e2sm_rc_ir_obj sm_common_ie_obj ds alg)
|
||||
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 e2sm_rc_ir_obj sm_common_ie_obj ds alg sm_common_enc_asn_obj_rc 3gpp_derived_ie_enc_asn_obj_rc)
|
||||
target_compile_definitions(e2_ran_func_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_CUUP)
|
||||
|
||||
|
||||
add_library(e2_ran_func_du_cucp_cuup STATIC
|
||||
${UE_ID_COMMON_E2SM_SRCS}
|
||||
init_ran_func.c
|
||||
read_setup_ran.c
|
||||
O-RAN/ran_e2sm_ue_id.c
|
||||
@@ -36,7 +77,7 @@ add_library(e2_ran_func_du_cucp_cuup STATIC
|
||||
../flexric/test/rnd/fill_rnd_data_tc.c
|
||||
)
|
||||
|
||||
target_link_libraries(e2_ran_func_du_cucp_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj ds)
|
||||
target_link_libraries(e2_ran_func_du_cucp_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj ds sm_common_enc_asn_obj_rc 3gpp_derived_ie_enc_asn_obj_rc)
|
||||
target_compile_definitions(e2_ran_func_du_cucp_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_DU NGRAN_GNB_CUCP NGRAN_GNB_CUUP)
|
||||
|
||||
# Current implementation:
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#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"
|
||||
#include "openair2/E2AP/flexric/src/lib/sm/enc/enc_ue_id.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@@ -226,7 +227,7 @@ static seq_report_sty_t fill_report_style_1(const char *report_name)
|
||||
|
||||
// Sequence of RAN Parameters Supported
|
||||
// [0 - 65535]
|
||||
report_style.sz_seq_ran_param = 1;
|
||||
report_style.sz_seq_ran_param = 2;
|
||||
report_style.ran_param = calloc_or_fail(report_style.sz_seq_ran_param, sizeof(seq_ran_param_3_t));
|
||||
|
||||
// RAN Parameter ID
|
||||
@@ -234,6 +235,7 @@ static seq_report_sty_t fill_report_style_1(const char *report_name)
|
||||
// 9.3.8
|
||||
// [1- 4294967295]
|
||||
report_style.ran_param[0].id = E2SM_RC_RS1_RRC_MESSAGE;
|
||||
report_style.ran_param[1].id = E2SM_RC_RS1_UE_ID;
|
||||
|
||||
// RAN Parameter Name
|
||||
// Mandatory
|
||||
@@ -241,11 +243,14 @@ static seq_report_sty_t fill_report_style_1(const char *report_name)
|
||||
// [1-150]
|
||||
const char ran_param_name_0[] = "RRC Message";
|
||||
report_style.ran_param[0].name = cp_str_to_ba(ran_param_name_0);
|
||||
const char ran_param_name_1[] = "UE ID";
|
||||
report_style.ran_param[1].name = cp_str_to_ba(ran_param_name_1);
|
||||
|
||||
// RAN Parameter Definition
|
||||
// Optional
|
||||
// 9.3.51
|
||||
report_style.ran_param[0].def = NULL;
|
||||
report_style.ran_param[1].def = NULL;
|
||||
|
||||
return report_style;
|
||||
}
|
||||
@@ -610,6 +615,79 @@ static void send_aper_ric_ind(const uint32_t ric_req_id, rc_ind_data_t* rc_ind_d
|
||||
printf("[E2 AGENT] Event for RIC request ID %d generated\n", ric_req_id);
|
||||
}
|
||||
|
||||
static rc_ind_data_t* fill_ue_id(const gNB_RRC_UE_t *rrc_ue_context, const uint16_t cond_id)
|
||||
{
|
||||
rc_ind_data_t* rc_ind = malloc_or_fail(sizeof(rc_ind_data_t));
|
||||
|
||||
// Generate Indication Header
|
||||
rc_ind->hdr.format = FORMAT_1_E2SM_RC_IND_HDR;
|
||||
rc_ind->hdr.frmt_1.ev_trigger_id = malloc_or_fail(sizeof(uint32_t));
|
||||
*rc_ind->hdr.frmt_1.ev_trigger_id = cond_id;
|
||||
|
||||
// Generate Indication Message
|
||||
rc_ind->msg.format = FORMAT_1_E2SM_RC_IND_MSG;
|
||||
|
||||
// Initialize RAN Parameter
|
||||
rc_ind->msg.frmt_1.sz_seq_ran_param = 1;
|
||||
rc_ind->msg.frmt_1.seq_ran_param = calloc_or_fail(rc_ind->msg.frmt_1.sz_seq_ran_param, sizeof(seq_ran_param_t));
|
||||
|
||||
// Fill the RAN Parameter details for UE ID
|
||||
rc_ind->msg.frmt_1.seq_ran_param[0].ran_param_id = E2SM_RC_RS1_UE_ID;
|
||||
rc_ind->msg.frmt_1.seq_ran_param[0].ran_param_val.type = ELEMENT_KEY_FLAG_FALSE_RAN_PARAMETER_VAL_TYPE;
|
||||
rc_ind->msg.frmt_1.seq_ran_param[0].ran_param_val.flag_false = malloc_or_fail(sizeof(ran_parameter_value_t));
|
||||
rc_ind->msg.frmt_1.seq_ran_param[0].ran_param_val.flag_false->type = OCTET_STRING_RAN_PARAMETER_VALUE;
|
||||
|
||||
const ngran_node_t node_type = get_e2_node_type();
|
||||
ue_id_e2sm_t ue_id_data = fill_ue_id_data[node_type](rrc_ue_context, 0, 0);
|
||||
|
||||
UEID_t enc_ue_id_data = enc_ue_id_asn(&ue_id_data);
|
||||
|
||||
const enum asn_transfer_syntax syntax = ATS_ALIGNED_BASIC_PER;
|
||||
asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, syntax, &asn_DEF_UEID, &enc_ue_id_data);
|
||||
assert(res.buffer != NULL && res.result.encoded > 0 && "[E2 agent] Failed to encode UE ID.");
|
||||
byte_array_t ba = {.buf = res.buffer, .len = res.result.encoded};
|
||||
|
||||
rc_ind->msg.frmt_1.seq_ran_param[0].ran_param_val.flag_false->octet_str_ran = copy_byte_array(ba);
|
||||
|
||||
// Call Process ID
|
||||
rc_ind->proc_id = NULL;
|
||||
|
||||
free_ue_id_e2sm(&ue_id_data);
|
||||
ASN_STRUCT_RESET(asn_DEF_UEID, &enc_ue_id_data);
|
||||
free(res.buffer);
|
||||
|
||||
return rc_ind;
|
||||
}
|
||||
|
||||
static void check_ue_id_cond(const gNB_RRC_UE_t *rrc_ue_context, const uint16_t class, const uint32_t msg_id, const uint32_t ric_req_id, const e2sm_rc_ev_trg_frmt_1_t *frmt_1)
|
||||
{
|
||||
for (size_t i = 0; i < frmt_1->sz_msg_ev_trg; i++) {
|
||||
msg_ev_trg_t *ev_item = &frmt_1->msg_ev_trg[i];
|
||||
if ((ev_item->msg_type == RRC_MSG_MSG_TYPE_EV_TRG && ev_item->rrc_msg.type == NR_RRC_MESSAGE_ID && ev_item->rrc_msg.nr == class && ev_item->rrc_msg.rrc_msg_id == msg_id) // rrcSetupComplete
|
||||
|| (ev_item->msg_type == NETWORK_INTERFACE_MSG_TYPE_EV_TRG && ev_item->net.ni_type == class)) { // "F1 UE Context Setup Request", but in the subscription the class (F1) can only be specified which translates to any F1 msg
|
||||
rc_ind_data_t* rc_ind_data = fill_ue_id(rrc_ue_context, ev_item->ev_trigger_cond_id);
|
||||
send_aper_ric_ind(ric_req_id, rc_ind_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void signal_ue_id(const gNB_RRC_UE_t *rrc_ue_context, const uint16_t class, const uint32_t msg_id)
|
||||
{
|
||||
pthread_mutex_lock(&rc_mutex);
|
||||
if (rc_subs_data.rs1_param4.data == NULL) {
|
||||
pthread_mutex_unlock(&rc_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t num_subs = seq_arr_size(&rc_subs_data.rs1_param4);
|
||||
for (size_t sub_idx = 0; sub_idx < num_subs; sub_idx++) {
|
||||
const ran_param_data_t data = *(const ran_param_data_t *)seq_arr_at(&rc_subs_data.rs1_param4, sub_idx);
|
||||
check_ue_id_cond(rrc_ue_context, class, msg_id, data.ric_req_id, &data.ev_tr.frmt_1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&rc_mutex);
|
||||
}
|
||||
|
||||
static void check_rrc_state(const gNB_RRC_UE_t *rrc_ue_context, const rrc_state_e2sm_rc_e rrc_state, const uint32_t ric_req_id, const e2sm_rc_ev_trg_frmt_4_t *frmt_4)
|
||||
{
|
||||
for (size_t i = 0; i < frmt_4->sz_ue_info_chng; i++) {
|
||||
@@ -716,6 +794,8 @@ static seq_arr_t *get_sa(const e2sm_rc_event_trigger_t *ev_tr, const uint32_t ra
|
||||
case FORMAT_1_E2SM_RC_EV_TRIGGER_FORMAT:
|
||||
if (ran_param_id == E2SM_RC_RS1_RRC_MESSAGE) {
|
||||
sa = &rc_subs_data.rs1_param3;
|
||||
} else if (ran_param_id == E2SM_RC_RS1_UE_ID) {
|
||||
sa = &rc_subs_data.rs1_param4;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -24,10 +24,13 @@
|
||||
|
||||
#include "openair2/RRC/NR/nr_rrc_defs.h"
|
||||
#include "openair2/E2AP/flexric/src/lib/3gpp/ie/rrc_msg_id.h"
|
||||
#include "openair2/E2AP/flexric/src/lib/3gpp/ie/network_interface_type.h"
|
||||
#include "openair2/E2AP/flexric/src/sm/rc_sm/ie/ir/rrc_state.h"
|
||||
|
||||
void signal_rrc_msg(const nr_rrc_class_e nr_channel, const uint32_t rrc_msg_id, const byte_array_t rrc_ba);
|
||||
|
||||
void signal_ue_id(const gNB_RRC_UE_t *rrc_ue_context, const uint16_t class, const uint32_t msg_id);
|
||||
|
||||
void signal_rrc_state_changed_to(const gNB_RRC_UE_t *rrc_ue_context, const rrc_state_e2sm_rc_e rrc_state);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,7 @@ void init_rc_subs_data(rc_subs_data_t *rc_subs_data)
|
||||
pthread_mutex_lock(&rc_mutex);
|
||||
// Initialize sequence array
|
||||
seq_arr_init(&rc_subs_data->rs1_param3, sizeof(ran_param_data_t));
|
||||
seq_arr_init(&rc_subs_data->rs1_param4, sizeof(ran_param_data_t));
|
||||
seq_arr_init(&rc_subs_data->rs4_param202, sizeof(ran_param_data_t));
|
||||
pthread_mutex_unlock(&rc_mutex);
|
||||
}
|
||||
@@ -65,6 +66,14 @@ void remove_rc_subs_data(rc_subs_data_t *rc_subs_data, uint32_t ric_req_id)
|
||||
seq_arr_erase(&rc_subs_data->rs1_param3, elm_rs1_param3.it);
|
||||
}
|
||||
|
||||
/* find the sequence element that matches RIC request ID */
|
||||
elm_arr_t elm_rs1_param4 = find_if(&rc_subs_data->rs1_param4, (void *)&ric_req_id, eq_int);
|
||||
ran_param_data_t *data_rs1_param4 = elm_rs1_param4.it;
|
||||
if (data_rs1_param4 != NULL) {
|
||||
free_e2sm_rc_event_trigger(&data_rs1_param4->ev_tr);
|
||||
seq_arr_erase(&rc_subs_data->rs1_param4, elm_rs1_param4.it);
|
||||
}
|
||||
|
||||
/* find the sequence element that matches RIC request ID */
|
||||
elm_arr_t elm_rs4_param202 = find_if(&rc_subs_data->rs4_param202, (void *)&ric_req_id, eq_int);
|
||||
ran_param_data_t *data_rs4_param202 = elm_rs4_param202.it;
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef struct ran_param_data {
|
||||
|
||||
typedef struct {
|
||||
seq_arr_t rs1_param3; // E2SM_RC_RS1_RRC_MESSAGE
|
||||
seq_arr_t rs1_param4; // E2SM_RC_RS1_UE_ID
|
||||
seq_arr_t rs4_param202; // E2SM_RC_RS4_RRC_STATE_CHANGED_TO
|
||||
} rc_subs_data_t;
|
||||
|
||||
|
||||
@@ -39,6 +39,11 @@
|
||||
#include "rrc_extern.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
|
||||
|
||||
#ifdef E2_AGENT
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
#include "openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h"
|
||||
#endif
|
||||
|
||||
static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t *drb_qos_in, F1AP_QoSFlowLevelQoSParameters_t *asn1_qosparam)
|
||||
{
|
||||
int type = drb_qos_in->qos_characteristics.qos_type;
|
||||
@@ -587,6 +592,11 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef E2_AGENT
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[0], f1ap_ue_context_setup_req->gNB_CU_ue_id);
|
||||
signal_ue_id(&ue_context_p->ue_context, F1_NETWORK_INTERFACE_TYPE, 0);
|
||||
#endif
|
||||
|
||||
// xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, (void *)pdu);
|
||||
// asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
// res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
|
||||
@@ -1648,6 +1648,11 @@ static void handle_rrcSetupComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const N
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef E2_AGENT
|
||||
const uint32_t msg_id = NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete;
|
||||
signal_ue_id(UE, UL_DCCH_NR_RRC_CLASS, msg_id);
|
||||
#endif
|
||||
|
||||
rrc_gNB_process_RRCSetupComplete(rrc, UE, setup_complete->criticalExtensions.choice.rrcSetupComplete);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user