Skip to content

Commit 9f42cae

Browse files
FabianEckermannFabian Eckermann
authored andcommitted
cu_cp,e1ap: release bearer context if last pdu session is released
1 parent ded5def commit 9f42cae

13 files changed

+285
-121
lines changed

lib/cu_cp/routines/pdu_session_resource_release_routine.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,18 @@ void pdu_session_resource_release_routine::operator()(
6767
next_config = up_resource_mng.calculate_update(release_cmd);
6868
}
6969

70-
// Inform CU-UP about the release of a bearer
71-
{
70+
// Inform the CU-UP about the release of the bearer context
71+
if (next_config.pdu_sessions_to_remove_list.size() == up_resource_mng.get_nof_pdu_sessions()) {
72+
bearer_context_release_command.ue_index = release_cmd.ue_index;
73+
bearer_context_release_command.cause = e1ap_cause_radio_network_t::unspecified;
74+
75+
/// NOTE: Only the Bearer Context at the CU-UP will be released. We don't want to release the UE.
76+
77+
// Request BearerContextRelease
78+
CORO_AWAIT(e1ap_bearer_ctxt_mng.handle_bearer_context_release_command(bearer_context_release_command));
79+
80+
} else { // Inform CU-UP about the release of a bearer
81+
7282
// prepare BearerContextModificationRequest and call e1 notifier
7383
bearer_context_modification_request.ue_index = release_cmd.ue_index;
7484

lib/e1ap/cu_cp/e1ap_cu_cp_impl.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,16 @@ e1ap_cu_cp_impl::handle_bearer_context_setup_request(const e1ap_bearer_context_s
9494
}
9595

9696
// add new e1ap_ue_context
97-
ue_ctxt_list.add_ue(request.ue_index, cu_cp_ue_e1ap_id);
97+
if (ue_ctxt_list.add_ue(request.ue_index, cu_cp_ue_e1ap_id) == nullptr) {
98+
logger.warning("Bearer Context Setup failed. Cause: bearer context already exists");
99+
return launch_async([](coro_context<async_task<e1ap_bearer_context_setup_response>>& ctx) mutable {
100+
CORO_BEGIN(ctx);
101+
e1ap_bearer_context_setup_response res;
102+
res.success = false;
103+
CORO_RETURN(res);
104+
});
105+
}
106+
98107
e1ap_ue_context& ue_ctxt = ue_ctxt_list[cu_cp_ue_e1ap_id];
99108

100109
e1ap_message e1ap_msg;
@@ -162,7 +171,7 @@ e1ap_cu_cp_impl::handle_bearer_context_release_command(const e1ap_bearer_context
162171

163172
fill_asn1_bearer_context_release_command(bearer_context_release_cmd, command);
164173

165-
return launch_async<bearer_context_release_procedure>(e1ap_msg, ue_ctxt.bearer_ev_mng, pdu_notifier, ue_ctxt.logger);
174+
return launch_async<bearer_context_release_procedure>(e1ap_msg, command.ue_index, ue_ctxt_list, pdu_notifier);
166175
}
167176

168177
void e1ap_cu_cp_impl::handle_message(const e1ap_message& msg)

lib/e1ap/cu_cp/procedures/bearer_context_release_procedure.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,33 @@
1111
#include "bearer_context_release_procedure.h"
1212
#include "cu_cp/e1ap_cu_cp_impl.h"
1313
#include "cu_cp/ue_context/e1ap_bearer_transaction_manager.h"
14+
#include "cu_cp/ue_context/e1ap_cu_cp_ue_context.h"
15+
#include "srsran/support/srsran_assert.h"
1416

1517
using namespace srsran;
1618
using namespace srsran::srs_cu_cp;
1719
using namespace asn1::e1ap;
1820

1921
constexpr std::chrono::milliseconds bearer_context_release_response_timeout{5000};
2022

21-
bearer_context_release_procedure::bearer_context_release_procedure(const e1ap_message& command_,
22-
e1ap_bearer_transaction_manager& ev_mng_,
23-
e1ap_message_notifier& e1ap_notif_,
24-
e1ap_ue_logger& logger_) :
25-
command(command_), ev_mng(ev_mng_), e1ap_notifier(e1ap_notif_), logger(logger_)
23+
bearer_context_release_procedure::bearer_context_release_procedure(const e1ap_message& command_,
24+
ue_index_t ue_index_,
25+
e1ap_ue_context_list& ue_ctxt_list_,
26+
e1ap_message_notifier& e1ap_notif_) :
27+
command(command_), ue_index(ue_index_), ue_ctxt_list(ue_ctxt_list_), e1ap_notifier(e1ap_notif_)
2628
{
29+
srsran_assert(ue_ctxt_list.contains(ue_index), "Bearer context does not exist in UE context list.");
2730
}
2831

2932
void bearer_context_release_procedure::operator()(coro_context<async_task<void>>& ctx)
3033
{
3134
CORO_BEGIN(ctx);
3235

33-
logger.log_debug("\"{}\" initialized", name());
36+
ue_ctxt_list[ue_index].logger.log_debug("\"{}\" initialized", name());
3437

3538
// Subscribe to respective publisher to receive BEARER CONTEXT RELEASE COMPLETE message.
36-
transaction_sink.subscribe_to(ev_mng.context_release_complete, bearer_context_release_response_timeout);
39+
transaction_sink.subscribe_to(ue_ctxt_list[ue_index].bearer_ev_mng.context_release_complete,
40+
bearer_context_release_response_timeout);
3741

3842
// Send command to CU-UP.
3943
send_bearer_context_release_command();
@@ -43,6 +47,8 @@ void bearer_context_release_procedure::operator()(coro_context<async_task<void>>
4347

4448
handle_bearer_context_release_complete();
4549

50+
/// NOTE: From this point on the UE context is removed and only locally stored variables can be used.
51+
4652
// Handle response from CU-UP and return bearer index
4753
CORO_RETURN();
4854
}
@@ -56,10 +62,13 @@ void bearer_context_release_procedure::send_bearer_context_release_command()
5662
void bearer_context_release_procedure::handle_bearer_context_release_complete()
5763
{
5864
if (transaction_sink.successful()) {
59-
logger.log_debug("\"{}\" finalized", name());
65+
ue_ctxt_list[ue_index].logger.log_debug("\"{}\" finalized", name());
6066

6167
} else {
62-
logger.log_warning("BearerContextReleaseComplete timeout");
63-
logger.log_error("\"{}\" failed", name());
68+
ue_ctxt_list[ue_index].logger.log_warning("BearerContextReleaseComplete timeout");
69+
ue_ctxt_list[ue_index].logger.log_error("\"{}\" failed", name());
6470
}
71+
72+
// Remove UE context
73+
ue_ctxt_list.remove_ue(ue_index);
6574
}

lib/e1ap/cu_cp/procedures/bearer_context_release_procedure.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ namespace srs_cu_cp {
2323
class bearer_context_release_procedure
2424
{
2525
public:
26-
bearer_context_release_procedure(const e1ap_message& command_,
27-
e1ap_bearer_transaction_manager& ev_mng_,
28-
e1ap_message_notifier& e1ap_notif_,
29-
e1ap_ue_logger& logger_);
26+
bearer_context_release_procedure(const e1ap_message& command_,
27+
ue_index_t ue_index_,
28+
e1ap_ue_context_list& ue_ctxt_list_,
29+
e1ap_message_notifier& e1ap_notif_);
3030

3131
void operator()(coro_context<async_task<void>>& ctx);
3232

@@ -39,10 +39,10 @@ class bearer_context_release_procedure
3939
/// Handles procedure result and returns back to procedure caller.
4040
void handle_bearer_context_release_complete();
4141

42-
const e1ap_message command;
43-
e1ap_bearer_transaction_manager& ev_mng;
44-
e1ap_message_notifier& e1ap_notifier;
45-
e1ap_ue_logger& logger;
42+
const e1ap_message command;
43+
ue_index_t ue_index;
44+
e1ap_ue_context_list& ue_ctxt_list;
45+
e1ap_message_notifier& e1ap_notifier;
4646

4747
protocol_transaction_outcome_observer<asn1::e1ap::bearer_context_release_complete_s> transaction_sink;
4848
};

lib/e1ap/cu_cp/ue_context/e1ap_cu_cp_ue_context.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ e1ap_ue_context* e1ap_ue_context_list::add_ue(ue_index_t ue_index, gnb_cu_cp_ue_
1919
srsran_assert(ue_index != ue_index_t::invalid, "Invalid ue_index={}", ue_index);
2020
srsran_assert(cu_cp_ue_e1ap_id != gnb_cu_cp_ue_e1ap_id_t::invalid, "Invalid cu_cp_ue_e1ap_id={}", cu_cp_ue_e1ap_id);
2121

22+
if (ue_index_to_ue_e1ap_id.find(ue_index) != ue_index_to_ue_e1ap_id.end()) {
23+
logger.error("ue={}: UE already exists", ue_index);
24+
return nullptr;
25+
}
26+
2227
auto ret = ues.emplace(std::piecewise_construct,
2328
std::forward_as_tuple(cu_cp_ue_e1ap_id),
2429
std::forward_as_tuple(ue_index, cu_cp_ue_e1ap_id, timers));

tests/unittests/cu_cp/cu_cp_test.cpp

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,7 @@ TEST_F(cu_cp_test, when_unsupported_inactivity_message_received_then_ue_context_
263263
/* AMF initiated PDU Session Release */
264264
//////////////////////////////////////////////////////////////////////////////////////
265265

266-
// Bearer Context Release is not sent even if last PDU session is removed. Only NGAP UE context release triggers Bearer
267-
// Context Release.
266+
// When multiple PDU sessions exist and not all of them are released, a BearerContextModification is sent to the CU-UP
268267
TEST_F(cu_cp_test, when_pdu_session_resource_release_command_received_then_modification_request_is_sent)
269268
{
270269
// Test preamble
@@ -275,15 +274,16 @@ TEST_F(cu_cp_test, when_pdu_session_resource_release_command_received_then_modif
275274
pci_t pci = 1;
276275
amf_ue_id_t amf_ue_id = uint_to_amf_ue_id(
277276
test_rgen::uniform_int<uint64_t>(amf_ue_id_to_uint(amf_ue_id_t::min), amf_ue_id_to_uint(amf_ue_id_t::max)));
278-
ran_ue_id_t ran_ue_id = uint_to_ran_ue_id(0);
279-
gnb_cu_cp_ue_e1ap_id_t cu_cp_ue_e1ap_id = int_to_gnb_cu_cp_ue_e1ap_id(0);
280-
gnb_cu_up_ue_e1ap_id_t cu_up_ue_e1ap_id = int_to_gnb_cu_up_ue_e1ap_id(0);
277+
ran_ue_id_t ran_ue_id = uint_to_ran_ue_id(0);
278+
std::vector<pdu_session_id_t> psis = {uint_to_pdu_session_id(1), uint_to_pdu_session_id(2)};
279+
gnb_cu_cp_ue_e1ap_id_t cu_cp_ue_e1ap_id = int_to_gnb_cu_cp_ue_e1ap_id(0);
280+
gnb_cu_up_ue_e1ap_id_t cu_up_ue_e1ap_id = int_to_gnb_cu_up_ue_e1ap_id(0);
281281

282282
// Connect AMF, DU, CU-UP
283283
test_preamble_all_connected(du_index, pci);
284284
// Attach UE
285285
test_preamble_ue_full_attach(
286-
du_index, du_ue_id, cu_ue_id, crnti, amf_ue_id, ran_ue_id, cu_cp_ue_e1ap_id, cu_up_ue_e1ap_id);
286+
du_index, du_ue_id, cu_ue_id, crnti, amf_ue_id, ran_ue_id, psis, cu_cp_ue_e1ap_id, cu_up_ue_e1ap_id);
287287

288288
// Inject PduSessionResourceReleaseCommand
289289
cu_cp_obj->get_ngap_message_handler().handle_message(
@@ -295,6 +295,41 @@ TEST_F(cu_cp_test, when_pdu_session_resource_release_command_received_then_modif
295295
asn1::e1ap::e1ap_elem_procs_o::init_msg_c::types_opts::bearer_context_mod_request);
296296
}
297297

298+
// When all active PDU sessions are released a BearerContextReleaseCommand is sent to the CU-UP
299+
TEST_F(cu_cp_test, when_all_pdu_sessions_get_released_then_bearer_context_release_command_is_sent)
300+
{
301+
// Test preamble
302+
du_index_t du_index = uint_to_du_index(0);
303+
gnb_cu_ue_f1ap_id_t cu_ue_id = int_to_gnb_cu_ue_f1ap_id(0);
304+
gnb_du_ue_f1ap_id_t du_ue_id = int_to_gnb_du_ue_f1ap_id(0);
305+
rnti_t crnti = to_rnti(0x4601);
306+
pci_t pci = 1;
307+
amf_ue_id_t amf_ue_id = uint_to_amf_ue_id(
308+
test_rgen::uniform_int<uint64_t>(amf_ue_id_to_uint(amf_ue_id_t::min), amf_ue_id_to_uint(amf_ue_id_t::max)));
309+
ran_ue_id_t ran_ue_id = uint_to_ran_ue_id(0);
310+
std::vector<pdu_session_id_t> psis = {uint_to_pdu_session_id(1)};
311+
gnb_cu_cp_ue_e1ap_id_t cu_cp_ue_e1ap_id = int_to_gnb_cu_cp_ue_e1ap_id(0);
312+
gnb_cu_up_ue_e1ap_id_t cu_up_ue_e1ap_id = int_to_gnb_cu_up_ue_e1ap_id(0);
313+
314+
// Connect AMF, DU, CU-UP
315+
test_preamble_all_connected(du_index, pci);
316+
// Attach UE
317+
test_preamble_ue_full_attach(
318+
du_index, du_ue_id, cu_ue_id, crnti, amf_ue_id, ran_ue_id, psis, cu_cp_ue_e1ap_id, cu_up_ue_e1ap_id);
319+
320+
// Inject PduSessionResourceReleaseCommand
321+
cu_cp_obj->get_ngap_message_handler().handle_message(
322+
generate_valid_pdu_session_resource_release_command(amf_ue_id, ran_ue_id, uint_to_pdu_session_id(1)));
323+
324+
// Check that the Bearer Context Release was sent to the CU-UP
325+
ASSERT_EQ(e1ap_gw.last_tx_pdus(0).back().pdu.type(), asn1::e1ap::e1ap_pdu_c::types_opts::options::init_msg);
326+
ASSERT_EQ(e1ap_gw.last_tx_pdus(0).back().pdu.init_msg().value.type().value,
327+
asn1::e1ap::e1ap_elem_procs_o::init_msg_c::types_opts::bearer_context_release_cmd);
328+
329+
// Check that no UE Context Release Request was sent to the AMF
330+
ASSERT_NE(n2_gw.last_ngap_msgs.back().pdu.type(), asn1::ngap::ngap_pdu_c::types_opts::options::init_msg);
331+
}
332+
298333
//////////////////////////////////////////////////////////////////////////////////////
299334
/* AMF initiated UE Context Release */
300335
//////////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)