Skip to content

Commit

Permalink
e2sm_rc: extending the RC to process recursive parameter structures
Browse files Browse the repository at this point in the history
  • Loading branch information
yagoda authored and codebot committed Apr 9, 2024
1 parent ee01313 commit 24a5645
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 38 deletions.
8 changes: 6 additions & 2 deletions include/srsran/du_manager/du_configurator.h
Expand Up @@ -15,14 +15,18 @@

namespace srsran {

struct du_mac_sched_control_config {
uint64_t ue_id;
struct control_config_params {
optional<unsigned> num_harq_processes;
optional<unsigned> num_harq_retransmissions;
optional<unsigned> min_prb_alloc;
optional<unsigned> max_prb_alloc;
};

struct du_mac_sched_control_config {
uint64_t ue_id;
std::vector<control_config_params> param_list;
};

struct du_mac_sched_control_config_response {
bool harq_processes_result;
bool min_prb_alloc_result;
Expand Down
12 changes: 6 additions & 6 deletions lib/du_manager/procedures/du_ue_ric_configuration_procedure.cpp
Expand Up @@ -74,12 +74,12 @@ async_task<mac_ue_reconfiguration_response> du_ue_ric_configuration_procedure::h
// Configure UE resource allocation parameters.
mac_request.sched_cfg.res_alloc_cfg.emplace();
auto& res_alloc_cfg = mac_request.sched_cfg.res_alloc_cfg.value();

res_alloc_cfg.pdsch_grant_size_limits = {request.min_prb_alloc.has_value() ? request.min_prb_alloc.value() : 0,
request.max_prb_alloc.has_value() ? request.max_prb_alloc.value()
: MAX_NOF_PRBS};
res_alloc_cfg.max_pdsch_harq_retxs = request.num_harq_retransmissions.has_value()
? request.num_harq_retransmissions.value()
// for now take first parameter set, in future we will have to support multiple parameter sets for different slices.
control_config_params req = request.param_list[0];
res_alloc_cfg.pdsch_grant_size_limits = {req.min_prb_alloc.has_value() ? req.min_prb_alloc.value() : 0,
req.max_prb_alloc.has_value() ? req.max_prb_alloc.value() : MAX_NOF_PRBS};
res_alloc_cfg.max_pdsch_harq_retxs = req.num_harq_retransmissions.has_value()
? req.num_harq_retransmissions.value()
: du_params.mac.sched_cfg.ue.max_nof_harq_retxs;
res_alloc_cfg.max_pusch_harq_retxs = res_alloc_cfg.max_pdsch_harq_retxs;

Expand Down
76 changes: 55 additions & 21 deletions lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.cpp
Expand Up @@ -52,6 +52,49 @@ e2sm_rc_control_action_du_executor_base::return_ctrl_failure(const e2sm_ric_cont
CORO_RETURN(e2sm_response);
});
}

void e2sm_rc_control_action_du_executor_base::parse_ran_parameter_value_false(
const ran_param_value_type_choice_elem_false_s& ran_p,
uint64_t ran_param_id,
uint64_t ue_id,
du_mac_sched_control_config& ctrl_cfg)
{
control_config_params cfg;
if (ran_param_id == 11) {
cfg.min_prb_alloc = ran_p.ran_param_value.value_int();
} else if (ran_param_id == 12) {
cfg.max_prb_alloc = ran_p.ran_param_value.value_int();
} else {
logger.error("Unknown RAN parameter ID %d", ran_param_id);
return;
}
ctrl_cfg.param_list.push_back(cfg);
}

void e2sm_rc_control_action_du_executor_base::parse_ran_parameter_value(const ran_param_value_type_c& ran_param,
uint64_t ran_param_id,
uint64_t ue_id,
du_mac_sched_control_config& ctrl_cfg)
{
if (ran_param.type() == ran_param_value_type_c::types_opts::ran_p_choice_list) {
for (auto& ran_p_list : ran_param.ran_p_choice_list().ran_param_list.list_of_ran_param) {
for (auto& ran_p : ran_p_list.seq_of_ran_params) {
if (action_params.find(ran_p.ran_param_id) != action_params.end()) {
parse_ran_parameter_value(ran_p.ran_param_value_type, ran_p.ran_param_id, ue_id, ctrl_cfg);
}
}
}
} else if (ran_param.type() == ran_param_value_type_c::types_opts::ran_p_choice_structure) {
for (auto& ran_seq : ran_param.ran_p_choice_structure().ran_param_structure.seq_of_ran_params) {
if (action_params.find(ran_seq.ran_param_id) != action_params.end()) {
parse_ran_parameter_value(ran_seq.ran_param_value_type, ran_seq.ran_param_id, ue_id, ctrl_cfg);
}
}
} else if (ran_param.type() == ran_param_value_type_c::types_opts::ran_p_choice_elem_false) {
parse_ran_parameter_value_false(ran_param.ran_p_choice_elem_false(), ran_param_id, ue_id, ctrl_cfg);
}
}

e2sm_rc_control_action_2_6_du_executor::e2sm_rc_control_action_2_6_du_executor(du_configurator& du_configurator_) :
e2sm_rc_control_action_du_executor_base(du_configurator_, 6)
{
Expand Down Expand Up @@ -90,7 +133,7 @@ async_task<e2sm_ric_control_response>
e2sm_rc_control_action_2_6_du_executor::execute_ric_control_action(const e2sm_ric_control_request& req)
{
du_mac_sched_control_config ctrl_config = convert_to_du_config_request(req);
if (!ctrl_config.ue_id) {
if (ctrl_config.param_list.empty()) {
return return_ctrl_failure(req);
}
return launch_async(
Expand All @@ -111,23 +154,14 @@ e2sm_rc_control_action_2_6_du_executor::convert_to_du_config_request(const e2sm_
variant_get<e2sm_rc_ctrl_hdr_s>(e2sm_req_.request_ctrl_hdr).ric_ctrl_hdr_formats.ctrl_hdr_format1();
const e2sm_rc_ctrl_msg_format1_s& ctrl_msg =
variant_get<e2sm_rc_ctrl_msg_s>(e2sm_req_.request_ctrl_msg).ric_ctrl_msg_formats.ctrl_msg_format1();

ctrl_config.ue_id = ctrl_hdr.ue_id.gnb_ue_id().amf_ue_ngap_id;
for (auto& ran_p : ctrl_msg.ran_p_list) {
if (action_params.find(ran_p.ran_param_id) != action_params.end()) {
if (ran_p.ran_param_id == 11) {
if (ran_p.ran_param_value_type.ran_p_choice_elem_false().ran_param_value_present) {
ctrl_config.min_prb_alloc = ran_p.ran_param_value_type.ran_p_choice_elem_false().ran_param_value.value_int();
ctrl_config.ue_id = ctrl_hdr.ue_id.gnb_du_ue_id().gnb_cu_ue_f1ap_id;
}
} else if (ran_p.ran_param_id == 12) {
if (ran_p.ran_param_value_type.ran_p_choice_elem_false().ran_param_value_present) {
ctrl_config.max_prb_alloc = ran_p.ran_param_value_type.ran_p_choice_elem_false().ran_param_value.value_int();
ctrl_config.ue_id = ctrl_hdr.ue_id.gnb_du_ue_id().gnb_cu_ue_f1ap_id;
}
}
} else {
logger.error("Parameter not supported");
return ctrl_config;
parse_ran_parameter_value(
ran_p.ran_param_value_type, ran_p.ran_param_id, ctrl_hdr.ue_id.gnb_du_ue_id().gnb_cu_ue_f1ap_id, ctrl_config);
}
if (ctrl_config.param_list.empty()) {
return {};
}
}
return ctrl_config;
Expand All @@ -151,18 +185,18 @@ e2sm_ric_control_response e2sm_rc_control_action_2_6_du_executor::convert_to_e2s
test_outcome.ran_param_id = 1;
test_outcome.ran_param_value.set_value_int() = 100;
ctrl_outcome.ran_p_list.push_back(test_outcome);

if (du_config_req_.min_prb_alloc.has_value()) {
control_config_params req = du_config_req_.param_list[0];
if (req.min_prb_alloc.has_value()) {
e2sm_rc_ctrl_outcome_format1_item_s min_prb_outcome;
min_prb_outcome.ran_param_id = 11;
min_prb_outcome.ran_param_value.set_value_int() = du_config_req_.min_prb_alloc.value();
min_prb_outcome.ran_param_value.set_value_int() = req.min_prb_alloc.value();
ctrl_outcome.ran_p_list.push_back(min_prb_outcome);
}

if (du_config_req_.max_prb_alloc.has_value()) {
if (req.max_prb_alloc.has_value()) {
e2sm_rc_ctrl_outcome_format1_item_s max_prb_outcome;
max_prb_outcome.ran_param_id = 12;
max_prb_outcome.ran_param_value.set_value_int() = du_config_req_.max_prb_alloc.value();
max_prb_outcome.ran_param_value.set_value_int() = req.max_prb_alloc.value();
ctrl_outcome.ran_p_list.push_back(max_prb_outcome);
}

Expand Down
8 changes: 8 additions & 0 deletions lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.h
Expand Up @@ -32,6 +32,14 @@ class e2sm_rc_control_action_du_executor_base : public e2sm_control_action_execu
uint32_t get_action_id() override;
bool ric_control_action_supported(const e2sm_ric_control_request& req) override = 0;
async_task<e2sm_ric_control_response> execute_ric_control_action(const e2sm_ric_control_request& req) override = 0;
void parse_ran_parameter_value_false(const asn1::e2sm::ran_param_value_type_choice_elem_false_s& ran_p,
uint64_t ran_param_id,
uint64_t ue_id,
du_mac_sched_control_config& ctrl_cfg);
void parse_ran_parameter_value(const asn1::e2sm::ran_param_value_type_c& ran_p,
uint64_t ran_param_id,
uint64_t ue_id,
du_mac_sched_control_config& ctrl_cfg);
async_task<e2sm_ric_control_response> return_ctrl_failure(const e2sm_ric_control_request& req);

protected:
Expand Down
Expand Up @@ -45,7 +45,9 @@ class du_ue_ric_config_tester : public du_manager_proc_tester, public ::testing:
TEST_F(du_ue_ric_config_tester,
when_new_ric_config_is_started_then_du_manager_starts_mac_config_and_waits_for_mac_response)
{
start_procedure(du_mac_sched_control_config{(uint64_t)test_ue->f1ap_ue_id, nullopt, nullopt, 5, 10});
std::vector<control_config_params> param_list;
param_list.emplace_back(control_config_params{nullopt, nullopt, 5, 10});
start_procedure(du_mac_sched_control_config{(uint64_t)test_ue->f1ap_ue_id, param_list});

ASSERT_TRUE(mac.last_ue_reconf_msg.has_value()) << "MAC should have received new configuration";
ASSERT_EQ(mac.last_ue_reconf_msg->ue_index, test_ue->ue_index);
Expand All @@ -60,7 +62,9 @@ TEST_F(du_ue_ric_config_tester,

TEST_F(du_ue_ric_config_tester, when_mac_finished_configuration_then_procedure_finishes)
{
start_procedure(du_mac_sched_control_config{(uint64_t)test_ue->f1ap_ue_id, nullopt, nullopt, 5, 10});
std::vector<control_config_params> param_list;
param_list.emplace_back(control_config_params{nullopt, nullopt, 5, 10});
start_procedure(du_mac_sched_control_config{(uint64_t)test_ue->f1ap_ue_id, param_list});

ASSERT_FALSE(proc_result().has_value()) << "The procedure should wait for MAC response";
mac.wait_ue_reconf.result = mac_ue_reconfiguration_response{test_ue->ue_index, true};
Expand All @@ -83,7 +87,9 @@ TEST_F(du_ue_ric_config_tester,
}));

// Start RIC UE config.
start_procedure(du_mac_sched_control_config{(uint64_t)test_ue->f1ap_ue_id, nullopt, nullopt, 5, 10});
std::vector<control_config_params> param_list;
param_list.emplace_back(control_config_params{nullopt, nullopt, 5, 10});
start_procedure(du_mac_sched_control_config{(uint64_t)test_ue->f1ap_ue_id, param_list});

// Status: RIC config procedure is waiting for previous procedure.
ASSERT_FALSE(mac.last_ue_reconf_msg.has_value())
Expand Down
6 changes: 3 additions & 3 deletions tests/unittests/e2/common/e2_test_helpers.h
Expand Up @@ -148,7 +148,7 @@ inline e2_message generate_ric_control_request_style2_action6(srslog::basic_logg
ric_control_request->ric_ctrl_ack_request_present = true;
ric_control_request->ric_ctrl_ack_request.value = ric_ctrl_ack_request_e::options::ack;

ric_control_request->ran_function_id = 1;
ric_control_request->ran_function_id = 3;
ric_control_request->ric_request_id.ric_requestor_id = 3;
ric_control_request->ric_request_id.ric_instance_id = 0;

Expand Down Expand Up @@ -220,7 +220,7 @@ inline e2_message generate_ric_control_request(srslog::basic_logger& logger,
ric_control_request->ric_ctrl_ack_request_present = true;
ric_control_request->ric_ctrl_ack_request.value = ric_ctrl_ack_request_e::options::ack;

ric_control_request->ran_function_id = 1;
ric_control_request->ran_function_id = 3;
ric_control_request->ric_request_id.ric_instance_id = 3;
ric_control_request->ric_request_id.ric_requestor_id = 0;

Expand Down Expand Up @@ -959,7 +959,7 @@ class e2_test_setup : public e2_test_base
e2sm_mngr = std::make_unique<e2sm_manager>(test_logger);
e2sm_mngr->add_e2sm_service("1.3.6.1.4.1.53148.1.2.2.2", std::move(e2sm_kpm_iface));
e2sm_mngr->add_e2sm_service("1.3.6.1.4.1.53148.1.1.2.3", std::move(e2sm_rc_iface));
e2sm_mngr->add_supported_ran_function(1, "1.3.6.1.4.1.53148.1.1.2.3");
e2sm_mngr->add_supported_ran_function(3, "1.3.6.1.4.1.53148.1.1.2.3");
e2_subscription_mngr = std::make_unique<e2_subscription_manager_impl>(*msg_notifier, *e2sm_mngr);
e2 = create_e2(cfg, factory, *msg_notifier, *e2_subscription_mngr, *e2sm_mngr);
gw = std::make_unique<dummy_network_gateway_data_handler>();
Expand Down
27 changes: 24 additions & 3 deletions tests/unittests/e2/e2_ric_control_procedure_test.cpp
Expand Up @@ -30,7 +30,7 @@ TEST_F(e2_test_setup, ric_control_procedure_setup)
ASSERT_EQ(msg.pdu.successful_outcome().value.type(),
asn1::e2ap::e2ap_elem_procs_o::successful_outcome_c::types_opts::ric_ctrl_ack);
auto ack = msg.pdu.successful_outcome().value.ric_ctrl_ack();
ASSERT_EQ(ack->ran_function_id, 1);
ASSERT_EQ(ack->ran_function_id, 3);
}

TEST_F(e2_test_setup, ric_control_procedure_setup2)
Expand All @@ -46,7 +46,7 @@ TEST_F(e2_test_setup, ric_control_procedure_setup2)
ASSERT_EQ(msg.pdu.successful_outcome().value.type(),
asn1::e2ap::e2ap_elem_procs_o::successful_outcome_c::types_opts::ric_ctrl_ack);
auto ack = msg.pdu.successful_outcome().value.ric_ctrl_ack();
ASSERT_EQ(ack->ran_function_id, 1);
ASSERT_EQ(ack->ran_function_id, 3);
}

TEST_F(e2_test_setup, ric_control_procedure_fail)
Expand All @@ -62,5 +62,26 @@ TEST_F(e2_test_setup, ric_control_procedure_fail)
ASSERT_EQ(msg.pdu.unsuccessful_outcome().value.type(),
asn1::e2ap::e2ap_elem_procs_o::unsuccessful_outcome_c::types_opts::ric_ctrl_fail);
auto ack = msg.pdu.unsuccessful_outcome().value.ric_ctrl_fail();
ASSERT_EQ(ack->ran_function_id, 1);
ASSERT_EQ(ack->ran_function_id, 3);
}

TEST_F(e2_test_setup, ric_control_procedure_packed)
{
uint8_t e2ap_ctrl_req[] = {
0x00, 0x04, 0x00, 0x76, 0x00, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x05, 0x00, 0x03, 0xfd, 0x00, 0x00, 0x00, 0x05,
0x00, 0x02, 0x00, 0x03, 0x00, 0x16, 0x00, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x10, 0x00,
0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x05, 0x00, 0x17, 0x00, 0x46, 0x45, 0x00, 0x00, 0x01, 0x00, 0x00, 0x60,
0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x02, 0x44, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x40, 0x00, 0x01,
0x00, 0x06, 0x2a, 0x00, 0x05, 0x30, 0x30, 0x31, 0x30, 0x31, 0x00, 0x07, 0x44, 0x00, 0x01, 0x00, 0x08, 0x2a,
0x00, 0x01, 0x31, 0x00, 0x09, 0x2a, 0x00, 0x01, 0x30, 0x00, 0x0a, 0x28, 0x80, 0x01, 0x05, 0x00, 0x0b, 0x28,
0x80, 0x01, 0x19, 0x00, 0x0c, 0x28, 0x80, 0x01, 0x64, 0x00, 0x15, 0x00, 0x01, 0x40};
byte_buffer e2ap_ctrl_req_buf = byte_buffer::create(e2ap_ctrl_req, e2ap_ctrl_req + sizeof(e2ap_ctrl_req)).value();
packer->handle_packed_pdu(std::move(e2ap_ctrl_req_buf));

asn1::cbit_ref bref(gw->last_pdu);
e2_message msg = {};
if (msg.pdu.unpack(bref) != asn1::SRSASN_SUCCESS) {
printf("Couldn't unpack E2 PDU");
}
ASSERT_EQ(msg.pdu.type().value, asn1::e2ap::e2ap_pdu_c::types_opts::successful_outcome);
}

0 comments on commit 24a5645

Please sign in to comment.