Skip to content

Commit

Permalink
cu-cp: fix for drb removal
Browse files Browse the repository at this point in the history
  • Loading branch information
andrepuschmann committed Apr 12, 2024
1 parent 8f2a3ea commit 31f2ed7
Show file tree
Hide file tree
Showing 15 changed files with 118 additions and 49 deletions.
2 changes: 1 addition & 1 deletion lib/cu_cp/du_processor/du_processor_impl.cpp
Expand Up @@ -395,7 +395,7 @@ du_processor_impl::handle_new_pdu_session_resource_release_command(
srsran_assert(ue != nullptr, "ue={}: Could not find DU UE", msg.ue_index);

return routine_mng->start_pdu_session_resource_release_routine(
msg, ngap_ctrl_notifier, task_sched, ue->get_up_resource_manager());
msg, ngap_ctrl_notifier, ue->get_rrc_ue_notifier(), task_sched, ue->get_up_resource_manager());
}

void du_processor_impl::handle_paging_message(cu_cp_paging_message& msg)
Expand Down
2 changes: 2 additions & 0 deletions lib/cu_cp/routine_managers/du_processor_routine_manager.cpp
Expand Up @@ -80,13 +80,15 @@ async_task<cu_cp_pdu_session_resource_release_response>
du_processor_routine_manager::start_pdu_session_resource_release_routine(
const cu_cp_pdu_session_resource_release_command& release_cmd,
du_processor_ngap_control_notifier& ngap_ctrl_notifier,
du_processor_rrc_ue_control_message_notifier& rrc_ue_ctrl_notifier,
du_processor_ue_task_scheduler& task_sched,
up_resource_manager& rrc_ue_up_resource_manager)
{
return launch_async<pdu_session_resource_release_routine>(release_cmd,
e1ap_ctrl_notifier,
f1ap_ue_ctxt_notifier,
ngap_ctrl_notifier,
rrc_ue_ctrl_notifier,
task_sched,
rrc_ue_up_resource_manager,
logger);
Expand Down
1 change: 1 addition & 0 deletions lib/cu_cp/routine_managers/du_processor_routine_manager.h
Expand Up @@ -49,6 +49,7 @@ class du_processor_routine_manager
async_task<cu_cp_pdu_session_resource_release_response>
start_pdu_session_resource_release_routine(const cu_cp_pdu_session_resource_release_command& release_cmd,
du_processor_ngap_control_notifier& ngap_ctrl_notifier,
du_processor_rrc_ue_control_message_notifier& rrc_ue_ctrl_notifier,
du_processor_ue_task_scheduler& task_sched,
up_resource_manager& rrc_ue_up_resource_manager);

Expand Down
Expand Up @@ -167,6 +167,7 @@ void inter_cu_handover_target_routine::operator()(
if (!fill_rrc_reconfig_args(rrc_reconfig_args,
ue_context_setup_request.srbs_to_be_setup_list,
next_config.pdu_sessions_to_setup_list,
{} /* No DRB to be removed */,
ue_context_setup_response.du_to_cu_rrc_info,
{} /* No NAS PDUs required */,
ue->get_rrc_ue_notifier().generate_meas_config(),
Expand Down
1 change: 1 addition & 0 deletions lib/cu_cp/routines/mobility/inter_du_handover_routine.cpp
Expand Up @@ -176,6 +176,7 @@ void inter_du_handover_routine::operator()(coro_context<async_task<cu_cp_inter_d
if (!fill_rrc_reconfig_args(rrc_reconfig_args,
target_ue_context_setup_request.srbs_to_be_setup_list,
next_config.pdu_sessions_to_setup_list,
{} /* No DRB to be removed */,
target_ue_context_setup_response.du_to_cu_rrc_info,
{} /* No NAS PDUs required */,
target_ue->get_rrc_ue_notifier().generate_meas_config(source_rrc_context.meas_cfg),
Expand Down
Expand Up @@ -151,16 +151,17 @@ void pdu_session_resource_modification_routine::operator()(
// prepare RRC Reconfiguration and call RRC UE notifier
{
// get NAS PDUs as received by AMF
std::map<pdu_session_id_t, byte_buffer> nas_pdus;
std::vector<byte_buffer> nas_pdus;
for (const auto& pdu_session : modify_request.pdu_session_res_modify_items) {
if (!pdu_session.nas_pdu.empty()) {
nas_pdus.emplace(pdu_session.pdu_session_id, pdu_session.nas_pdu);
nas_pdus.push_back(pdu_session.nas_pdu);
}
}

if (!fill_rrc_reconfig_args(rrc_reconfig_args,
{},
next_config.pdu_sessions_to_modify_list,
{} /* No extra DRB to be removed */,
ue_context_modification_response.du_to_cu_rrc_info,
nas_pdus,
rrc_ue_notifier.generate_meas_config(),
Expand Down
64 changes: 60 additions & 4 deletions lib/cu_cp/routines/pdu_session_resource_release_routine.cpp
Expand Up @@ -21,6 +21,7 @@
*/

#include "pdu_session_resource_release_routine.h"
#include "pdu_session_routine_helpers.h"

using namespace srsran;
using namespace srsran::srs_cu_cp;
Expand All @@ -31,19 +32,35 @@ pdu_session_resource_release_routine::pdu_session_resource_release_routine(
du_processor_e1ap_control_notifier& e1ap_ctrl_notif_,
du_processor_f1ap_ue_context_notifier& f1ap_ue_ctxt_notif_,
du_processor_ngap_control_notifier& ngap_ctrl_notifier_,
du_processor_rrc_ue_control_message_notifier& rrc_ue_notifier_,
du_processor_ue_task_scheduler& task_sched_,
up_resource_manager& rrc_ue_up_resource_manager_,
srslog::basic_logger& logger_) :
release_cmd(release_cmd_),
e1ap_ctrl_notifier(e1ap_ctrl_notif_),
f1ap_ue_ctxt_notifier(f1ap_ue_ctxt_notif_),
ngap_ctrl_notifier(ngap_ctrl_notifier_),
rrc_ue_notifier(rrc_ue_notifier_),
task_sched(task_sched_),
rrc_ue_up_resource_manager(rrc_ue_up_resource_manager_),
logger(logger_)
{
}

// Handle RRC reconfiguration result.
bool handle_procedure_response(cu_cp_pdu_session_resource_release_response& response_msg,
const cu_cp_pdu_session_resource_release_command& release_cmd,
bool rrc_reconfig_result,
const srslog::basic_logger& logger)
{
// Let all PDU sessions fail if response is negative.
if (!rrc_reconfig_result) {
// TODO: decide how to manage negative RRC reconfig result
}

return rrc_reconfig_result;
}

void pdu_session_resource_release_routine::operator()(
coro_context<async_task<cu_cp_pdu_session_resource_release_response>>& ctx)
{
Expand All @@ -54,7 +71,7 @@ void pdu_session_resource_release_routine::operator()(
// Perform initial sanity checks on incoming message.
if (!rrc_ue_up_resource_manager.validate_request(release_cmd)) {
logger.warning("ue={}: \"{}\" Invalid PduSessionResourceReleaseCommand", release_cmd.ue_index, name());
CORO_EARLY_RETURN(generate_pdu_session_resource_release_response(false));
CORO_EARLY_RETURN(handle_pdu_session_resource_release_response(false));
}

{
Expand Down Expand Up @@ -113,13 +130,48 @@ void pdu_session_resource_release_routine::operator()(
}
}

CORO_RETURN(generate_pdu_session_resource_release_response(true));
{
// prepare RRC Reconfiguration and call RRC UE notifier
{
// get NAS PDUs as received by AMF
std::vector<byte_buffer> nas_pdus;
if (!release_cmd.nas_pdu.empty()) {
nas_pdus.push_back(release_cmd.nas_pdu);
}

if (!fill_rrc_reconfig_args(rrc_reconfig_args,
{},
next_config.pdu_sessions_to_modify_list,
next_config.drb_to_remove_list,
ue_context_modification_response.du_to_cu_rrc_info,
nas_pdus,
rrc_ue_notifier.generate_meas_config(),
false,
false,
false,
logger)) {
logger.warning("ue={}: \"{}\" Failed to fill RrcReconfiguration", release_cmd.ue_index, name());
CORO_EARLY_RETURN(handle_pdu_session_resource_release_response(false));
}
}

CORO_AWAIT_VALUE(rrc_reconfig_result, rrc_ue_notifier.on_rrc_reconfiguration_request(rrc_reconfig_args));

// Handle RRC Reconfiguration result.
if (handle_procedure_response(response_msg, release_cmd, rrc_reconfig_result, logger) == false) {
logger.warning("ue={}: \"{}\" RRC reconfiguration failed", release_cmd.ue_index, name());
CORO_EARLY_RETURN(handle_pdu_session_resource_release_response(false));
}
}

CORO_RETURN(handle_pdu_session_resource_release_response(true));
}

cu_cp_pdu_session_resource_release_response
pdu_session_resource_release_routine::generate_pdu_session_resource_release_response(bool success)
pdu_session_resource_release_routine::handle_pdu_session_resource_release_response(bool success)
{
if (success) {
logger.debug("ue={}: \"{}\" finalized", release_cmd.ue_index, name());
for (const auto& setup_item : release_cmd.pdu_session_res_to_release_list_rel_cmd) {
cu_cp_pdu_session_res_released_item_rel_res item;
item.pdu_session_id = setup_item.pdu_session_id;
Expand All @@ -136,7 +188,11 @@ pdu_session_resource_release_routine::generate_pdu_session_resource_release_resp
}

rrc_ue_up_resource_manager.apply_config_update(result);
} else {
logger.info("ue={}: \"{}\" failed", release_cmd.ue_index, name());

// Trigger UE context release request?
}

return response_msg;
}
}
25 changes: 15 additions & 10 deletions lib/cu_cp/routines/pdu_session_resource_release_routine.h
Expand Up @@ -38,9 +38,11 @@ class pdu_session_resource_release_routine
du_processor_e1ap_control_notifier& e1ap_ctrl_notif_,
du_processor_f1ap_ue_context_notifier& f1ap_ue_ctxt_notif_,
du_processor_ngap_control_notifier& ngap_ctrl_notifier_,
du_processor_rrc_ue_control_message_notifier& rrc_ue_notifier_,
du_processor_ue_task_scheduler& task_sched_,
up_resource_manager& rrc_ue_up_resource_manager_,
srslog::basic_logger& logger_);

up_resource_manager& rrc_ue_up_resource_manager_,
srslog::basic_logger& logger_);

void operator()(coro_context<async_task<cu_cp_pdu_session_resource_release_response>>& ctx);

Expand All @@ -50,30 +52,33 @@ class pdu_session_resource_release_routine
void fill_e1ap_bearer_context_modification_request(e1ap_bearer_context_modification_request& e1ap_request);
bool valid_5qi(const qos_flow_setup_request_item& flow);

cu_cp_pdu_session_resource_release_response generate_pdu_session_resource_release_response(bool success);
cu_cp_pdu_session_resource_release_response handle_pdu_session_resource_release_response(bool success);

const cu_cp_pdu_session_resource_release_command release_cmd;

up_config_update next_config;

du_processor_e1ap_control_notifier& e1ap_ctrl_notifier; // to trigger bearer context setup at CU-UP
du_processor_f1ap_ue_context_notifier& f1ap_ue_ctxt_notifier; // to trigger UE context modification at DU
du_processor_ngap_control_notifier& ngap_ctrl_notifier; // to request UE release
du_processor_ue_task_scheduler& task_sched; // to schedule UE release request (over NGAP)
up_resource_manager& rrc_ue_up_resource_manager; // to get RRC DRB config
srslog::basic_logger& logger;
du_processor_e1ap_control_notifier& e1ap_ctrl_notifier; // to trigger bearer context setup at CU-UP
du_processor_f1ap_ue_context_notifier& f1ap_ue_ctxt_notifier; // to trigger UE context modification at DU
du_processor_ngap_control_notifier& ngap_ctrl_notifier; // to request UE release
du_processor_rrc_ue_control_message_notifier& rrc_ue_notifier; // to trigger RRC Reconfiguration at UE
du_processor_ue_task_scheduler& task_sched; // to schedule UE release request (over NGAP)
up_resource_manager& rrc_ue_up_resource_manager; // to get RRC DRB config
srslog::basic_logger& logger;

// (sub-)routine requests
f1ap_ue_context_modification_request ue_context_mod_request;
e1ap_bearer_context_modification_request bearer_context_modification_request;
e1ap_bearer_context_release_command bearer_context_release_command;
rrc_reconfiguration_procedure_request rrc_reconfig_args;
cu_cp_ue_context_release_request ue_context_release_request;

// (sub-)routine results
cu_cp_pdu_session_resource_release_response response_msg;
f1ap_ue_context_modification_response ue_context_modification_response; // to inform DU about the new DRBs
e1ap_bearer_context_modification_response
bearer_context_modification_response; // to inform CU-UP about the new TEID for UL F1u traffic
bearer_context_modification_response; // to inform CU-UP about the new TEID for UL F1u traffic
bool rrc_reconfig_result = false; // the final UE reconfiguration
};

} // namespace srs_cu_cp
Expand Down
5 changes: 3 additions & 2 deletions lib/cu_cp/routines/pdu_session_resource_setup_routine.cpp
Expand Up @@ -211,16 +211,17 @@ void pdu_session_resource_setup_routine::operator()(
// if default DRB is being setup, SRB2 needs to be setup as well
{
// get NAS PDUs as received by AMF
std::map<pdu_session_id_t, byte_buffer> nas_pdus;
std::vector<byte_buffer> nas_pdus;
for (const auto& pdu_session : setup_msg.pdu_session_res_setup_items) {
if (!pdu_session.pdu_session_nas_pdu.empty()) {
nas_pdus.emplace(pdu_session.pdu_session_id, pdu_session.pdu_session_nas_pdu);
nas_pdus.push_back(pdu_session.pdu_session_nas_pdu);
}
}

if (!fill_rrc_reconfig_args(rrc_reconfig_args,
ue_context_mod_request.srbs_to_be_setup_mod_list,
next_config.pdu_sessions_to_setup_list,
{} /* No extra DRB to be removed */,
ue_context_modification_response.du_to_cu_rrc_info,
nas_pdus,
next_config.initial_context_creation ? rrc_ue_notifier.generate_meas_config()
Expand Down
30 changes: 20 additions & 10 deletions lib/cu_cp/routines/pdu_session_routine_helpers.cpp
Expand Up @@ -88,8 +88,9 @@ bool srsran::srs_cu_cp::fill_rrc_reconfig_args(
rrc_reconfiguration_procedure_request& rrc_reconfig_args,
const slotted_id_vector<srb_id_t, f1ap_srbs_to_be_setup_mod_item>& srbs_to_be_setup_mod_list,
const std::map<pdu_session_id_t, up_pdu_session_context_update>& pdu_sessions,
const std::vector<drb_id_t>& drb_to_remove,
const f1ap_du_to_cu_rrc_info& du_to_cu_rrc_info,
const std::map<pdu_session_id_t, byte_buffer>& nas_pdus,
const std::vector<byte_buffer>& nas_pdus,
const optional<rrc_meas_cfg> rrc_meas_cfg,
bool reestablish_srbs,
bool reestablish_drbs,
Expand Down Expand Up @@ -142,18 +143,27 @@ bool srsran::srs_cu_cp::fill_rrc_reconfig_args(
radio_bearer_config.drb_to_add_mod_list.emplace(drb_to_add.first, drb_to_add_mod);
}

for (const auto& drb_to_remove : pdu_session_to_add_mod.second.drb_to_remove) {
radio_bearer_config.drb_to_release_list.push_back(drb_to_remove);
// Remove DRB from a PDU session (PDU session itself still exists with out DRBs).
for (const auto& drb_id : pdu_session_to_add_mod.second.drb_to_remove) {
radio_bearer_config.drb_to_release_list.push_back(drb_id);
}
}

// append NAS PDUs as received by AMF
if (!nas_pdus.empty()) {
if (nas_pdus.find(pdu_session_to_add_mod.first) != nas_pdus.end()) {
if (!nas_pdus.at(pdu_session_to_add_mod.first).empty()) {
rrc_recfg_v1530_ies.ded_nas_msg_list.push_back(nas_pdus.at(pdu_session_to_add_mod.first).copy());
}
}
// Remove DRB (if not already) that are not associated with any PDU session anymore.
for (const auto& drb_id : drb_to_remove) {
if (std::any_of(radio_bearer_config.drb_to_release_list.begin(),
radio_bearer_config.drb_to_release_list.end(),
[drb_id](const auto& item) { return item == drb_id; })) {
// The DRB is already set to be removed.
continue;
}

radio_bearer_config.drb_to_release_list.push_back(drb_id);
}

// append NAS PDUs as received by AMF
for (const auto& nas_pdu : nas_pdus) {
rrc_recfg_v1530_ies.ded_nas_msg_list.push_back(nas_pdu.copy());
}

if (update_keys) {
Expand Down
8 changes: 5 additions & 3 deletions lib/cu_cp/routines/pdu_session_routine_helpers.h
Expand Up @@ -61,8 +61,9 @@ void fill_drb_to_remove_list(std::vector<drb_id_t>& e1ap_drb_to_remove_lis
/// \brief Fill RRC Reconfiguration message content.
/// \param[out] rrc_reconfig_args The RRC Reconfiguration Arguments struct to fill.
/// \param[in] srbs_to_be_setup_mod_list SRBs to be setup (only needed if default DRB is being setup).
/// \param[in] pdu_sessions The PDU sessions to add to the reconfiguration.
/// \param[in] ue_context_modification_response The UE Context Modification Response as received by the DU.
/// \param[in] pdu_sessions The PDU sessions to add/mod in the reconfiguration.
/// \param[in] drb_to_remove DRB to remove from the configurations.
/// \param[in] du_to_cu_rrc_info RRC container forwarded from the DU to the CU.
/// \param[in] nas_pdus NAS PDUs to forward to the UE as received by the AMF.
/// \param[in] rrc_meas_cfg Optional measurement config to include in Reconfiguration.
/// \param[in] reestablish_srbs Whether to request SRB reestablishment.
Expand All @@ -73,8 +74,9 @@ bool fill_rrc_reconfig_args(
rrc_reconfiguration_procedure_request& rrc_reconfig_args,
const slotted_id_vector<srb_id_t, f1ap_srbs_to_be_setup_mod_item>& srbs_to_be_setup_mod_list,
const std::map<pdu_session_id_t, up_pdu_session_context_update>& pdu_sessions,
const std::vector<drb_id_t>& drb_to_remove,
const f1ap_du_to_cu_rrc_info& du_to_cu_rrc_info,
const std::map<pdu_session_id_t, byte_buffer>& nas_pdus,
const std::vector<byte_buffer>& nas_pdus,
const optional<rrc_meas_cfg> rrc_meas_cfg,
bool reestablish_srbs,
bool reestablish_drbs,
Expand Down
Expand Up @@ -124,6 +124,7 @@ void reestablishment_context_modification_routine::operator()(coro_context<async
if (!fill_rrc_reconfig_args(rrc_reconfig_args,
srbs_to_setup_list,
pdu_sessions_to_setup_list,
{} /* No DRB to be removed */,
ue_context_modification_response.du_to_cu_rrc_info,
{},
{} /* TODO: include meas config in context*/,
Expand Down

0 comments on commit 31f2ed7

Please sign in to comment.