mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-18 15:10:29 +00:00
Compare commits
13 Commits
pre-commit
...
o1-telnet-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ce1003265 | ||
|
|
a21d103696 | ||
|
|
604b20f8eb | ||
|
|
656a038638 | ||
|
|
e7912c4df0 | ||
|
|
31c3421c7c | ||
|
|
7a288984c8 | ||
|
|
a17920e91b | ||
|
|
e1de68f8e8 | ||
|
|
2664acbcd4 | ||
|
|
f4930d3a6c | ||
|
|
2d1ec40b08 | ||
|
|
93804cf3e5 |
@@ -37,7 +37,9 @@
|
||||
#include "openair2/RRC/NR/nr_rrc_config.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c"
|
||||
#include "openair2/RRC/NR/nr_rrc_defs.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "common/ngran_types.h"
|
||||
|
||||
#define ERROR_MSG_RET(mSG, aRGS...) do { prnt("FAILURE: " mSG, ##aRGS); return 1; } while (0)
|
||||
|
||||
@@ -58,6 +60,17 @@
|
||||
#define MNC "nrcelldu3gpp:mnc"
|
||||
#define SD "nrcelldu3gpp:sd"
|
||||
#define SST "nrcelldu3gpp:sst"
|
||||
#define SSBSCS "nrcelldu3gpp:ssbSubCarrierSpacing"
|
||||
#define SSBPRD "nrcelldu3gpp:ssbPeriodicity"
|
||||
#define SSBOFF "nrcelldu3gpp:ssbOffset"
|
||||
#define SSBDUR "nrcelldu3gpp:ssbDuration"
|
||||
|
||||
#define PMAX "nrfreqrel3gpp:pMax"
|
||||
#define CELLLOCALID "nrcellcu3gpp:cellLocalId"
|
||||
#define CU_MCC "nrcellcu3gpp:mcc"
|
||||
#define CU_MNC "nrcellcu3gpp:mnc"
|
||||
#define CU_SST "nrcellcu3gpp:sst"
|
||||
#define CU_SD "nrcellcu3gpp:sd"
|
||||
|
||||
typedef struct b {
|
||||
long int dl;
|
||||
@@ -77,13 +90,57 @@ typedef struct ue_stat {
|
||||
} \
|
||||
} \
|
||||
|
||||
static int get_stats(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
/* Tree management functions */
|
||||
static int du_compare(const nr_rrc_du_container_t *a, const nr_rrc_du_container_t *b)
|
||||
{
|
||||
if (buf)
|
||||
ERROR_MSG_RET("no parameter allowed\n");
|
||||
if (a->assoc_id > b->assoc_id)
|
||||
return 1;
|
||||
if (a->assoc_id == b->assoc_id)
|
||||
return 0;
|
||||
return -1; /* a->assoc_id < b->assoc_id */
|
||||
}
|
||||
|
||||
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||
AssertFatal(mac != NULL, "need MAC\n");
|
||||
RB_GENERATE/*_STATIC*/(rrc_du_tree, nr_rrc_du_container_t, entries, du_compare);
|
||||
static void get_cu_stats(telnet_printfunc_t prnt, gNB_RRC_INST *rrc)
|
||||
{
|
||||
/* This is not thread safe; we just read, so hope for the best */
|
||||
|
||||
prnt("{\n");
|
||||
prnt(" \"o1-config\": {\n");
|
||||
prnt(" \"NRCELLCU\": [\n"); // list?
|
||||
|
||||
nr_rrc_du_container_t *it = NULL;
|
||||
bool first = true;
|
||||
RB_FOREACH (it, rrc_du_tree, &rrc->dus) {
|
||||
|
||||
const f1ap_served_cell_info_t *ci = &it->setup_req->cell[0].info;
|
||||
if (!first)
|
||||
prnt(",\n");
|
||||
prnt(" {\n");
|
||||
prnt(" \""CELLLOCALID"\": %d,\n", ci->nr_cellid);
|
||||
prnt(" \""CU_MCC"\": \"%03d\",\n", ci->plmn.mcc);
|
||||
prnt(" \""CU_MNC"\": \"%0*d\",\n", ci->plmn.mnc_digit_length, ci->plmn.mnc);
|
||||
prnt(" \""CU_SST"\": %d,\n", ci->nssai[0].sst);
|
||||
prnt(" \""CU_SD "\": %d\n", ci->nssai[0].sd);
|
||||
prnt(" }");
|
||||
first = false;
|
||||
}
|
||||
prnt("\n ],\n");
|
||||
|
||||
/* TODO harmonize this between DU&CU to be able to have one in monolithic */
|
||||
prnt(" \"device\": {\n");
|
||||
prnt(" \"gNBId\": %d,\n", rrc->node_id);
|
||||
prnt(" \"gnbName\": \"%s\",\n", rrc->node_name);
|
||||
prnt(" \"vendor\": \"OpenAirInterface\"\n");
|
||||
prnt(" }\n");
|
||||
prnt(" }\n");
|
||||
|
||||
prnt("}\n");
|
||||
prnt("OK\n");
|
||||
}
|
||||
|
||||
static void get_du_stats(telnet_printfunc_t prnt, gNB_MAC_INST *mac)
|
||||
{
|
||||
NR_SCHED_LOCK(&mac->sched_lock);
|
||||
|
||||
const f1ap_setup_req_t *sr = mac->f1_config.setup_req;
|
||||
@@ -173,7 +230,11 @@ static int get_stats(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
prnt(" \"" MCC "\": \"%03d\",\n", cell_info->plmn.mcc);
|
||||
prnt(" \"" MNC "\": \"%0*d\",\n", cell_info->plmn.mnc_digit_length, cell_info->plmn.mnc);
|
||||
prnt(" \"" SD "\": %d,\n", cell_info->nssai[0].sd);
|
||||
prnt(" \"" SST "\": %d\n", cell_info->nssai[0].sst);
|
||||
prnt(" \"" SST "\": %d,\n", cell_info->nssai[0].sst);
|
||||
prnt(" \"" SSBSCS "\": %d,\n", 30);
|
||||
prnt(" \"" SSBPRD "\": %d,\n", 20);
|
||||
prnt(" \"" SSBOFF "\": %d,\n", 0);
|
||||
prnt(" \"" SSBDUR "\": %d\n", 1);
|
||||
prnt(" },\n");
|
||||
prnt(" \"device\": {\n");
|
||||
prnt(" \"gnbId\": %d,\n", sr->gNB_DU_id);
|
||||
@@ -194,7 +255,24 @@ static int get_stats(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
prnt(" }\n");
|
||||
prnt("}\n");
|
||||
prnt("OK\n");
|
||||
|
||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||
}
|
||||
|
||||
static int get_stats(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (buf)
|
||||
ERROR_MSG_RET("no parameter allowed\n");
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||
bool is_cu = rrc != NULL && (NODE_IS_MONOLITHIC(rrc->node_type) || NODE_IS_CU(rrc->node_type));
|
||||
gNB_MAC_INST *mac = RC.nrmac ? RC.nrmac[0] : NULL;
|
||||
bool is_du = mac != NULL;
|
||||
if (is_cu)
|
||||
get_cu_stats(prnt, rrc);
|
||||
else if (is_du)
|
||||
get_du_stats(prnt, mac);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,22 +53,16 @@ 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)
|
||||
static seq_ev_trg_style_t fill_ev_tr_format_4(void)
|
||||
{
|
||||
// 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];
|
||||
seq_ev_trg_style_t ev_trig_style = {0};
|
||||
|
||||
// RIC Event Trigger Style Type
|
||||
// Mandatory
|
||||
// 9.3.3
|
||||
// 6.2.2.2.
|
||||
// INTEGER
|
||||
ev_trig_style->style = 4;
|
||||
// INTEGER
|
||||
ev_trig_style.style = 4;
|
||||
|
||||
// RIC Event Trigger Style Name
|
||||
// Mandatory
|
||||
@@ -76,14 +70,57 @@ static void fill_rc_ev_trig(ran_func_def_ev_trig_t* ev_trig)
|
||||
// 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);
|
||||
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;
|
||||
ev_trig_style.format = FORMAT_4_E2SM_RC_EV_TRIGGER_FORMAT;
|
||||
|
||||
return ev_trig_style;
|
||||
}
|
||||
|
||||
static seq_ev_trg_style_t fill_ev_tr_format_1(void)
|
||||
{
|
||||
seq_ev_trg_style_t ev_trig_style = {0};
|
||||
|
||||
// RIC Event Trigger Style Type
|
||||
// Mandatory
|
||||
// 9.3.3
|
||||
// 6.2.2.2.
|
||||
// INTEGER
|
||||
ev_trig_style.style = 1;
|
||||
|
||||
// RIC Event Trigger Style Name
|
||||
// Mandatory
|
||||
// 9.3.4
|
||||
// 6.2.2.3
|
||||
//PrintableString(SIZE(1..150,...))
|
||||
const char ev_style_name[] = "Message Event";
|
||||
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_1_E2SM_RC_EV_TRIGGER_FORMAT;
|
||||
|
||||
return ev_trig_style;
|
||||
}
|
||||
|
||||
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 = 2;
|
||||
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");
|
||||
|
||||
ev_trig->seq_ev_trg_style[0] = fill_ev_tr_format_1();
|
||||
ev_trig->seq_ev_trg_style[1] = fill_ev_tr_format_4();
|
||||
|
||||
// Sequence of RAN Parameters for L2 Variables
|
||||
// [0 - 65535]
|
||||
@@ -106,22 +143,16 @@ static void fill_rc_ev_trig(ran_func_def_ev_trig_t* ev_trig)
|
||||
ev_trig->seq_ran_param_id_cell = NULL;
|
||||
}
|
||||
|
||||
static void fill_rc_report(ran_func_def_report_t* report)
|
||||
static seq_report_sty_t fill_report_style_4(void)
|
||||
{
|
||||
// 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 = {0};
|
||||
|
||||
seq_report_sty_t* report_style = &report->seq_report_sty[0];
|
||||
|
||||
// RIC Report Style Type
|
||||
// RIC Report Style Type
|
||||
// Mandatory
|
||||
// 9.3.3
|
||||
// 6.2.2.2.
|
||||
// INTEGER
|
||||
report_style->report_type = 4;
|
||||
report_style.report_type = 4;
|
||||
|
||||
// RIC Report Style Name
|
||||
// Mandatory
|
||||
@@ -129,59 +160,147 @@ static void fill_rc_report(ran_func_def_report_t* report)
|
||||
// 6.2.2.3.
|
||||
// PrintableString(SIZE(1..150,...))
|
||||
const char report_name[] = "UE Information";
|
||||
report_style->name = cp_str_to_ba(report_name);
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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.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 = E2SM_RC_RS4_RRC_STATE_CHANGED_TO;
|
||||
report_style.ran_param[0].id = E2SM_RC_RS4_RRC_STATE_CHANGED_TO;
|
||||
|
||||
// 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);
|
||||
const char ran_param_name[] = "RRC State Changed To";
|
||||
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;
|
||||
report_style.ran_param[0].def = NULL;
|
||||
|
||||
return report_style;
|
||||
}
|
||||
|
||||
static seq_report_sty_t fill_report_style_1(void)
|
||||
{
|
||||
seq_report_sty_t report_style = {0};
|
||||
|
||||
// RIC Report Style Type
|
||||
// Mandatory
|
||||
// 9.3.3
|
||||
// 6.2.2.2.
|
||||
// INTEGER
|
||||
report_style.report_type = 1;
|
||||
|
||||
// RIC Report Style Name
|
||||
// Mandatory
|
||||
// 9.3.4
|
||||
// 6.2.2.3.
|
||||
// PrintableString(SIZE(1..150,...))
|
||||
const char report_name[] = "Message Copy";
|
||||
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_1_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_1_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 = E2SM_RC_RS1_RRC_MESSAGE;
|
||||
|
||||
// RAN Parameter Name
|
||||
// Mandatory
|
||||
// 9.3.9
|
||||
// [1-150]
|
||||
const char ran_param_name_0[] = "RRC Message";
|
||||
report_style.ran_param[0].name = cp_str_to_ba(ran_param_name_0);
|
||||
|
||||
// RAN Parameter Definition
|
||||
// Optional
|
||||
// 9.3.51
|
||||
report_style.ran_param[0].def = NULL;
|
||||
|
||||
return report_style;
|
||||
}
|
||||
|
||||
static void fill_rc_report(ran_func_def_report_t* report)
|
||||
{
|
||||
// Sequence of REPORT styles
|
||||
// [1 - 63]
|
||||
report->sz_seq_report_sty = 2;
|
||||
report->seq_report_sty = calloc(report->sz_seq_report_sty, sizeof(seq_report_sty_t));
|
||||
assert(report->seq_report_sty != NULL && "Memory exhausted");
|
||||
|
||||
report->seq_report_sty[0] = fill_report_style_1();
|
||||
report->seq_report_sty[1] = fill_report_style_4();
|
||||
}
|
||||
|
||||
static void fill_rc_control(ran_func_def_ctrl_t* ctrl)
|
||||
@@ -562,6 +681,68 @@ void signal_rrc_state_changed_to(const gNB_RRC_UE_t *rrc_ue_context, const rc_sm
|
||||
pthread_mutex_unlock(&rc_mutex);
|
||||
}
|
||||
|
||||
static rc_ind_data_t* fill_rrc_msg_copy(const byte_array_t rrc_ba, const uint16_t cond_id)
|
||||
{
|
||||
rc_ind_data_t* rc_ind = calloc(1, sizeof(rc_ind_data_t));
|
||||
assert(rc_ind != NULL && "Memory exhausted");
|
||||
|
||||
// Generate Indication Header
|
||||
rc_ind->hdr.format = FORMAT_1_E2SM_RC_IND_HDR;
|
||||
rc_ind->hdr.frmt_1.ev_trigger_id = calloc(1, sizeof(uint32_t));
|
||||
assert(rc_ind->hdr.frmt_1.ev_trigger_id != NULL && "Memory exhausted");
|
||||
*rc_ind->hdr.frmt_1.ev_trigger_id = cond_id;
|
||||
|
||||
// Generate Indication Message
|
||||
rc_ind->msg.format = FORMAT_1_E2SM_RC_IND_MSG;
|
||||
|
||||
// Sequence of
|
||||
// RAN Parameter
|
||||
rc_ind->msg.frmt_1.sz_seq_ran_param = 1;
|
||||
rc_ind->msg.frmt_1.seq_ran_param = calloc(rc_ind->msg.frmt_1.sz_seq_ran_param, sizeof(seq_ran_param_t));
|
||||
assert(rc_ind->msg.frmt_1.seq_ran_param != NULL && "Memory exhausted");
|
||||
|
||||
rc_ind->msg.frmt_1.seq_ran_param[0].ran_param_id = E2SM_RC_RS1_RRC_MESSAGE;
|
||||
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 = calloc(1, sizeof(ran_parameter_value_t));
|
||||
assert(rc_ind->msg.frmt_1.seq_ran_param[0].ran_param_val.flag_false != NULL && "Memory exhausted");
|
||||
rc_ind->msg.frmt_1.seq_ran_param[0].ran_param_val.flag_false->type = OCTET_STRING_RAN_PARAMETER_VALUE;
|
||||
|
||||
rc_ind->msg.frmt_1.seq_ran_param[0].ran_param_val.flag_false->octet_str_ran = copy_byte_array(rrc_ba);
|
||||
|
||||
return rc_ind;
|
||||
}
|
||||
|
||||
static void check_rrc_msg_copy(const nr_rrc_class_e nr_channel, const uint32_t rrc_msg_id, const byte_array_t rrc_ba, 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++) {
|
||||
if (frmt_1->msg_ev_trg[i].msg_type != RRC_MSG_MSG_TYPE_EV_TRG)
|
||||
continue;
|
||||
if (frmt_1->msg_ev_trg[i].rrc_msg.type != NR_RRC_MESSAGE_ID)
|
||||
continue;
|
||||
if (frmt_1->msg_ev_trg[i].rrc_msg.nr == nr_channel && frmt_1->msg_ev_trg[i].rrc_msg.rrc_msg_id == rrc_msg_id) {
|
||||
rc_ind_data_t* rc_ind_data = fill_rrc_msg_copy(rrc_ba, frmt_1->msg_ev_trg[i].ev_trigger_cond_id);
|
||||
send_aper_ric_ind(ric_req_id, rc_ind_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void signal_rrc_msg(const nr_rrc_class_e nr_channel, const uint32_t rrc_msg_id, const byte_array_t rrc_ba)
|
||||
{
|
||||
pthread_mutex_lock(&rc_mutex);
|
||||
if (rc_subs_data.rs1_param3.data == NULL) {
|
||||
pthread_mutex_unlock(&rc_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t num_subs = seq_arr_size(&rc_subs_data.rs1_param3);
|
||||
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_param3, sub_idx);
|
||||
check_rrc_msg_copy(nr_channel, rrc_msg_id, rrc_ba, data.ric_req_id, &data.ev_tr.frmt_1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&rc_mutex);
|
||||
}
|
||||
|
||||
static void free_aperiodic_subscription(uint32_t ric_req_id)
|
||||
{
|
||||
remove_rc_subs_data(&rc_subs_data, ric_req_id);
|
||||
@@ -572,6 +753,12 @@ static seq_arr_t *get_sa(const e2sm_rc_event_trigger_t *ev_tr, const uint32_t ra
|
||||
seq_arr_t *sa = NULL;
|
||||
|
||||
switch (ev_tr->format) {
|
||||
case FORMAT_1_E2SM_RC_EV_TRIGGER_FORMAT:
|
||||
if (ran_param_id == E2SM_RC_RS1_RRC_MESSAGE) {
|
||||
sa = &rc_subs_data.rs1_param3;
|
||||
}
|
||||
break;
|
||||
|
||||
case FORMAT_4_E2SM_RC_EV_TRIGGER_FORMAT:
|
||||
if (ran_param_id == E2SM_RC_RS4_RRC_STATE_CHANGED_TO) {
|
||||
sa = &rc_subs_data.rs4_param202;
|
||||
|
||||
@@ -23,6 +23,17 @@
|
||||
#define RAN_FUNC_SM_RAN_CTRL_EXTERN_AGENT_H
|
||||
|
||||
#include "openair2/RRC/NR/nr_rrc_defs.h"
|
||||
#include "openair2/E2AP/flexric/src/lib/3gpp/ie/rrc_msg_id.h"
|
||||
|
||||
typedef enum {
|
||||
RRC_SETUP_COMPLETE_MSG,
|
||||
XN_NG_HANDOVER_REQUEST, // not supported in OAI
|
||||
F1_UE_CONTEXT_SETUP_REQUEST,
|
||||
|
||||
END_EVENT_TRIGGER_MSG,
|
||||
} message_type_e;
|
||||
|
||||
void signal_rrc_msg(const nr_rrc_class_e nr_channel, const uint32_t rrc_msg_id, const byte_array_t rrc_ba);
|
||||
|
||||
typedef enum { RC_SM_RRC_CONNECTED, RC_SM_RRC_INACTIVE, RC_SM_RRC_IDLE, RC_SM_RRC_ANY } rc_sm_rrc_state_e;
|
||||
void signal_rrc_state_changed_to(const gNB_RRC_UE_t *rrc_ue_context, const rc_sm_rrc_state_e rrc_state);
|
||||
|
||||
@@ -41,6 +41,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->rs4_param202, sizeof(ran_param_data_t));
|
||||
pthread_mutex_unlock(&rc_mutex);
|
||||
}
|
||||
@@ -57,9 +58,19 @@ void remove_rc_subs_data(rc_subs_data_t *rc_subs_data, uint32_t ric_req_id)
|
||||
{
|
||||
pthread_mutex_lock(&rc_mutex);
|
||||
/* find the sequence element that matches RIC request ID */
|
||||
elm_arr_t elm = find_if(&rc_subs_data->rs4_param202, (void *)&ric_req_id, eq_int);
|
||||
ran_param_data_t *data = elm.it;
|
||||
free_e2sm_rc_event_trigger(&data->ev_tr);
|
||||
seq_arr_erase(&rc_subs_data->rs4_param202, elm.it);
|
||||
elm_arr_t elm_rs1_param3 = find_if(&rc_subs_data->rs1_param3, (void *)&ric_req_id, eq_int);
|
||||
ran_param_data_t *data_rs1_param3 = elm_rs1_param3.it;
|
||||
if (data_rs1_param3 != NULL) {
|
||||
free_e2sm_rc_event_trigger(&data_rs1_param3->ev_tr);
|
||||
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_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;
|
||||
if (data_rs4_param202 != NULL) {
|
||||
free_e2sm_rc_event_trigger(&data_rs4_param202->ev_tr);
|
||||
seq_arr_erase(&rc_subs_data->rs4_param202, elm_rs4_param202.it);
|
||||
}
|
||||
pthread_mutex_unlock(&rc_mutex);
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ typedef struct ran_param_data {
|
||||
} ran_param_data_t;
|
||||
|
||||
typedef struct {
|
||||
seq_arr_t rs1_param3; // E2SM_RC_RS1_RRC_MESSAGE
|
||||
seq_arr_t rs4_param202; // E2SM_RC_RS4_RRC_STATE_CHANGED_TO
|
||||
} rc_subs_data_t;
|
||||
|
||||
|
||||
Submodule openair2/E2AP/flexric updated: beabdd072c...468387ed39
@@ -404,6 +404,31 @@ static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai,
|
||||
return ssl->list.count;
|
||||
}
|
||||
|
||||
static F1AP_ProtocolExtensionContainer_10696P34_t *write_slice_info(int num_ssi, const nssai_t *nssai)
|
||||
{
|
||||
if (num_ssi == 0)
|
||||
return NULL;
|
||||
|
||||
F1AP_ProtocolExtensionContainer_10696P34_t *p = calloc_or_fail(1, sizeof(*p));
|
||||
asn1cSequenceAdd(p->list, F1AP_ServedPLMNs_ItemExtIEs_t, served_plmns_itemExtIEs);
|
||||
served_plmns_itemExtIEs->criticality = F1AP_Criticality_ignore;
|
||||
served_plmns_itemExtIEs->id = F1AP_ProtocolIE_ID_id_TAISliceSupportList;
|
||||
served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList;
|
||||
F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList;
|
||||
|
||||
for (int s = 0; s < num_ssi; s++) {
|
||||
asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, slice);
|
||||
const nssai_t *n = &nssai[s];
|
||||
INT8_TO_OCTET_STRING(n->sst, &slice->sNSSAI.sST);
|
||||
if (n->sd != 0xffffff) {
|
||||
asn1cCalloc(slice->sNSSAI.sD, tmp);
|
||||
INT24_TO_OCTET_STRING(n->sd, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief F1AP Setup Request memory management
|
||||
*/
|
||||
@@ -468,6 +493,8 @@ static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_
|
||||
asn1cSequenceAdd(scell_info.servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item);
|
||||
// PLMN Identity (M)
|
||||
MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity);
|
||||
// NSSAIs (O)
|
||||
servedPLMN_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)write_slice_info(c->num_ssi, c->nssai);
|
||||
// NR-Mode-Info (M)
|
||||
F1AP_NR_Mode_Info_t *nR_Mode_Info = &scell_info.nR_Mode_Info;
|
||||
if (c->mode == F1AP_MODE_FDD) { // FDD Info
|
||||
|
||||
@@ -57,6 +57,11 @@ bool eq_f1ap_cell_info(const f1ap_served_cell_info_t *a, const f1ap_served_cell_
|
||||
return false;
|
||||
if (a->tac)
|
||||
_F1_EQ_CHECK_INT(*a->tac, *b->tac);
|
||||
_F1_EQ_CHECK_INT(a->num_ssi, b->num_ssi);
|
||||
for (int i = 0; i < a->num_ssi; ++i) {
|
||||
_F1_EQ_CHECK_INT(a->nssai[i].sst, b->nssai[i].sst);
|
||||
_F1_EQ_CHECK_INT(a->nssai[i].sd, b->nssai[i].sd);
|
||||
}
|
||||
_F1_EQ_CHECK_INT(a->mode, b->mode);
|
||||
if (a->mode == F1AP_MODE_TDD) {
|
||||
/* TDD */
|
||||
|
||||
@@ -573,6 +573,15 @@ static void rrc_gNB_generate_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_
|
||||
|
||||
LOG_UE_DL_EVENT(ue_p, "Generate RRCReconfiguration (bytes %d, xid %d)\n", size, xid);
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, buffer, size);
|
||||
|
||||
#ifdef E2_AGENT
|
||||
const uint32_t rrc_msg_id = 1; // TS 38.331, section 6.2.1 ("DL-DCCH-Message")
|
||||
byte_array_t buffer_ba = {.len = size};
|
||||
buffer_ba.buf = calloc(size, sizeof(uint8_t));
|
||||
assert(buffer_ba.buf != NULL && "Memory exhausted");
|
||||
memcpy(buffer_ba.buf, buffer, size);
|
||||
signal_rrc_msg(DL_DCCH_NR_RRC_CLASS, rrc_msg_id, buffer_ba);
|
||||
#endif
|
||||
}
|
||||
|
||||
void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
||||
@@ -1725,6 +1734,13 @@ static int rrc_gNB_decode_dcch(gNB_RRC_INST *rrc, const f1ap_ul_rrc_message_t *m
|
||||
}
|
||||
|
||||
if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) {
|
||||
#ifdef E2_AGENT
|
||||
// 38.331 Sec 6.2.1: message index of UL-DCCH-Message
|
||||
const uint32_t rrc_msg_id = ul_dcch_msg->message.choice.c1->present;
|
||||
byte_array_t buffer_ba = {.len = msg->rrc_container_length};
|
||||
buffer_ba.buf = msg->rrc_container;
|
||||
signal_rrc_msg(UL_DCCH_NR_RRC_CLASS, rrc_msg_id, buffer_ba);
|
||||
#endif
|
||||
switch (ul_dcch_msg->message.choice.c1->present) {
|
||||
case NR_UL_DCCH_MessageType__c1_PR_NOTHING:
|
||||
LOG_I(NR_RRC, "Received PR_NOTHING on UL-DCCH-Message\n");
|
||||
|
||||
Reference in New Issue
Block a user