Skip to content

Commit 47916e4

Browse files
frankistcodebot
authored andcommitted
cu-cp: refactor ue rrc context update in the CU-CP
1 parent 3a782e0 commit 47916e4

File tree

14 files changed

+165
-145
lines changed

14 files changed

+165
-145
lines changed

include/srsran/cu_cp/cu_cp_ue_messages.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,5 @@ struct rrc_ue_transfer_context {
3131
bool is_inter_cu_handover = false;
3232
};
3333

34-
/// \brief The UE creation is triggered from the F1AP.
35-
/// It carries an RRC container and the C-RNTI if the DU sent an Initial UL RRC transfer. If the user is created
36-
/// during handover the RNTI is only allocated after the Random Access.
37-
struct cu_cp_ue_creation_request {
38-
ue_index_t ue_index = ue_index_t::invalid;
39-
nr_cell_global_id_t cgi;
40-
uint32_t tac;
41-
byte_buffer du_to_cu_rrc_container;
42-
rnti_t c_rnti;
43-
optional<rrc_ue_transfer_context> rrc_context;
44-
};
45-
4634
} // namespace srs_cu_cp
4735
} // namespace srsran

include/srsran/f1ap/cu_cp/f1ap_cu.h

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,21 @@ class f1ap_rrc_message_notifier
9999
virtual void on_ul_dcch_pdu(const srb_id_t srb_id, byte_buffer pdu) = 0;
100100
};
101101

102-
/// Response provided by the CU-CP to the F1AP-CU when a UE context creation in the CU-CP is requested.
103-
struct cu_cp_ue_creation_response {
104-
ue_index_t ue_index = ue_index_t::invalid;
102+
/// \brief Request made by the F1AP-CU to create a RRC context for an existing UE context in the CU-CP.
103+
///
104+
/// This request should be made once the C-RNTI and cell of the UE is known. That generally corresponds to the moment
105+
/// a Initial UL RRC Message or a F1AP UE Context Setup Response are received.
106+
struct ue_rrc_context_creation_request {
107+
ue_index_t ue_index;
108+
rnti_t c_rnti;
109+
nr_cell_global_id_t cgi;
110+
byte_buffer du_to_cu_rrc_container;
111+
optional<rrc_ue_transfer_context> prev_context;
112+
};
113+
114+
/// \brief Response by CU-CP to F1AP-CU request to create UE RRC context.
115+
struct ue_rrc_context_creation_response {
116+
/// Notifier to be used by the F1AP to push new RRC PDUs to the UE RRC layer.
105117
f1ap_rrc_message_notifier* f1ap_rrc_notifier = nullptr;
106118
};
107119

@@ -125,10 +137,12 @@ class f1ap_du_processor_notifier : public du_setup_notifier
125137
public:
126138
virtual ~f1ap_du_processor_notifier() = default;
127139

128-
/// \brief Notifies the DU processor to create a UE.
129-
/// \param[in] msg The ue creation message.
130-
/// \return Returns a UE creation complete message containing the index of the created UE and its SRB notifiers.
131-
virtual cu_cp_ue_creation_response on_ue_creation_request(const cu_cp_ue_creation_request& msg) = 0;
140+
/// \brief Notifies the CU-CP to create a new UE instance.
141+
virtual ue_index_t on_new_cu_cp_ue_required() = 0;
142+
143+
/// \brief Notifies the CU-CP that an RRC context has been created for an existing CU-CP UE.
144+
virtual ue_rrc_context_creation_response
145+
on_ue_rrc_context_creation_request(const ue_rrc_context_creation_request& req) = 0;
132146

133147
/// \brief Indicates the reception of a UE Context Release Request (gNB-DU initiated) as per TS 38.473
134148
/// section 8.3.2.

lib/cu_cp/adapters/f1ap_adapters.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,17 @@ class f1ap_du_processor_adapter : public f1ap_du_processor_notifier
6969

7070
du_index_t get_du_index() override { return du_f1ap_handler->get_du_index(); }
7171

72-
cu_cp_ue_creation_response on_ue_creation_request(const cu_cp_ue_creation_request& msg) override
72+
ue_index_t on_new_cu_cp_ue_required() override
7373
{
7474
srsran_assert(du_f1ap_handler != nullptr, "F1AP handler must not be nullptr");
75-
return du_f1ap_handler->handle_ue_creation_request(msg);
75+
return du_f1ap_handler->allocate_new_ue_index();
76+
}
77+
78+
ue_rrc_context_creation_response
79+
on_ue_rrc_context_creation_request(const ue_rrc_context_creation_request& req) override
80+
{
81+
srsran_assert(du_f1ap_handler != nullptr, "F1AP handler must not be nullptr");
82+
return du_f1ap_handler->handle_ue_rrc_context_creation_request(req);
7683
}
7784

7885
void on_du_initiated_ue_context_release_request(const f1ap_ue_context_release_request& req) override

lib/cu_cp/du_processor/du_processor_impl.cpp

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -245,57 +245,45 @@ bool du_processor_impl::create_rrc_ue(du_ue& ue,
245245
return true;
246246
}
247247

248-
cu_cp_ue_creation_response du_processor_impl::handle_ue_creation_request(const cu_cp_ue_creation_request& msg)
248+
ue_rrc_context_creation_response
249+
du_processor_impl::handle_ue_rrc_context_creation_request(const ue_rrc_context_creation_request& req)
249250
{
250-
srsran_assert(config_helpers::is_valid(msg.cgi), "ue={}: Invalid CGI", msg.ue_index);
251-
srsran_assert(msg.c_rnti != rnti_t::INVALID_RNTI, "ue={}: Invalid C-RNTI", msg.ue_index);
251+
srsran_assert(req.ue_index != ue_index_t::invalid, "Invalid UE index");
252+
srsran_assert(req.c_rnti != rnti_t::INVALID_RNTI, "ue={}: Invalid C-RNTI", req.ue_index);
253+
srsran_assert(config_helpers::is_valid(req.cgi), "ue={}: Invalid CGI", req.ue_index);
252254

253255
// Check that creation message is valid
254-
du_cell_index_t pcell_index = find_cell(msg.cgi.nci);
256+
du_cell_index_t pcell_index = find_cell(req.cgi.nci);
255257
if (pcell_index == du_cell_index_t::invalid) {
256-
logger.warning("ue={}: Could not find cell with cell_id={}", msg.ue_index, msg.cgi.nci);
258+
logger.warning("ue={}: Could not find cell with NCI={}", req.ue_index, req.cgi.nci);
259+
cu_cp_notifier.on_ue_removal_required(req.ue_index);
257260
return {};
258261
}
259262
const pci_t pci = cell_db.at(pcell_index).pci;
260263

261-
// Allocate new UE index.
262-
ue_index_t ue_index = msg.ue_index;
263-
if (ue_index == ue_index_t::invalid) {
264-
// It's a new UE. Allocate new UE index.
265-
ue_index = allocate_new_ue_index();
266-
if (ue_index == ue_index_t::invalid) {
267-
logger.warning("ue={}: Could not create UE context", ue_index);
268-
return {};
269-
}
270-
}
271-
272-
// Create new UE context
273-
du_ue* ue = ue_manager.set_ue_du_context(ue_index, context.id, pci, msg.c_rnti);
264+
// Create new UE RRC context
265+
du_ue* ue = ue_manager.set_ue_du_context(req.ue_index, context.id, pci, req.c_rnti);
274266
if (ue == nullptr) {
275-
logger.warning("ue={}: Could not create UE context", ue_index);
267+
logger.warning("ue={}: Could not create UE context", req.ue_index);
276268
return {};
277269
}
278-
279-
// Set parameters from creation message
280270
ue->set_pcell_index(pcell_index);
281271

282272
// Create RRC UE. If the DU-to-CU-RRC-Container is empty, the UE will be rejected.
283-
if (not create_rrc_ue(*ue, msg.c_rnti, msg.cgi, msg.du_to_cu_rrc_container.copy(), std::move(msg.rrc_context))) {
284-
logger.warning("ue={}: Could not create RRC UE object", ue_index);
285-
ue_manager.remove_ue(ue_index);
273+
if (not create_rrc_ue(*ue, req.c_rnti, req.cgi, req.du_to_cu_rrc_container.copy(), std::move(req.prev_context))) {
274+
logger.warning("ue={}: Could not create RRC UE object", req.ue_index);
286275
return {};
287276
}
288-
rrc_ue_interface* rrc_ue = rrc->find_ue(ue_index);
289-
f1ap_rrc_ue_adapters[ue_index] = {};
290-
f1ap_rrc_ue_adapters.at(ue_index).connect_rrc_ue(rrc_ue->get_ul_ccch_pdu_handler(),
291-
rrc_ue->get_ul_dcch_pdu_handler());
277+
rrc_ue_interface* rrc_ue = rrc->find_ue(req.ue_index);
278+
f1ap_rrc_ue_adapters[req.ue_index] = {};
279+
f1ap_rrc_ue_adapters.at(req.ue_index)
280+
.connect_rrc_ue(rrc_ue->get_ul_ccch_pdu_handler(), rrc_ue->get_ul_dcch_pdu_handler());
292281

293282
// Signal back to F1AP that the UE was successfully created.
294-
cu_cp_ue_creation_response response;
295-
response.ue_index = ue_index;
296-
response.f1ap_rrc_notifier = &f1ap_rrc_ue_adapters.at(ue_index);
283+
ue_rrc_context_creation_response response;
284+
response.f1ap_rrc_notifier = &f1ap_rrc_ue_adapters.at(req.ue_index);
297285

298-
logger.info("ue={} c-rnti={}: UE created", ue->get_ue_index(), msg.c_rnti);
286+
logger.info("ue={} c-rnti={}: UE created", ue->get_ue_index(), req.c_rnti);
299287

300288
return response;
301289
}

lib/cu_cp/du_processor/du_processor_impl.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,10 @@ class du_processor_impl : public du_processor_impl_interface, public du_setup_ha
5555
size_t get_nof_ues() const override { return ue_manager.get_nof_du_ues(context.du_index); };
5656

5757
// du_processor_f1ap_interface
58-
du_setup_result handle_du_setup_request(const du_setup_request& req) override;
59-
ue_index_t allocate_new_ue_index() override;
60-
cu_cp_ue_creation_response handle_ue_creation_request(const cu_cp_ue_creation_request& msg) override;
58+
du_setup_result handle_du_setup_request(const du_setup_request& req) override;
59+
ue_index_t allocate_new_ue_index() override;
60+
ue_rrc_context_creation_response
61+
handle_ue_rrc_context_creation_request(const ue_rrc_context_creation_request& req) override;
6162
void handle_du_initiated_ue_context_release_request(const f1ap_ue_context_release_request& request) override;
6263
ue_update_complete_message handle_ue_update_request(const ue_update_message& msg) override;
6364

lib/cu_cp/du_processor/du_processor_impl_interface.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,13 @@ class du_processor_f1ap_interface
4343
/// \brief Allocate a new UE index.
4444
virtual ue_index_t allocate_new_ue_index() = 0;
4545

46-
/// \brief Create a new UE context.
47-
/// \param[in] msg The UE creation message.
48-
/// \return Returns a UE creation complete message containing the index of the created UE and its SRB notifiers.
49-
virtual cu_cp_ue_creation_response handle_ue_creation_request(const cu_cp_ue_creation_request& msg) = 0;
46+
/// \brief Request to create a new UE RRC context.
47+
///
48+
/// This method should be called when a C-RNTI and PCell are assigned to a UE.
49+
/// \param req
50+
/// \return
51+
virtual ue_rrc_context_creation_response
52+
handle_ue_rrc_context_creation_request(const ue_rrc_context_creation_request& req) = 0;
5053

5154
/// \brief Update existing UE object.
5255
virtual ue_update_complete_message handle_ue_update_request(const ue_update_message& msg) = 0;

lib/f1ap/cu_cp/f1ap_cu_impl.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -254,34 +254,42 @@ void f1ap_cu_impl::handle_initial_ul_rrc_message(const init_ul_rrc_msg_transfer_
254254
return;
255255
}
256256

257-
// Request UE context creation to CU-CP.
258-
cu_cp_ue_creation_request ue_creation_msg = {};
259-
ue_creation_msg.cgi = cgi;
260-
ue_creation_msg.c_rnti = crnti;
257+
// Create CU-CP UE instance.
258+
const ue_index_t ue_index = du_processor_notifier.on_new_cu_cp_ue_required();
259+
if (ue_index == ue_index_t::invalid) {
260+
logger.warning("du_ue_f1ap_id={}: Dropping InitialULRRCMessageTransfer. Cause: CU-CP UE creation failed",
261+
msg->gnb_du_ue_f1ap_id);
262+
return;
263+
}
264+
265+
// Update the UE RRC context (e.g. C-RNTI, PCell) in the CU-CP.
266+
ue_rrc_context_creation_request req;
267+
req.ue_index = ue_index;
268+
req.c_rnti = crnti;
269+
req.cgi = cgi;
261270
if (msg->du_to_cu_rrc_container_present) {
262-
ue_creation_msg.du_to_cu_rrc_container = byte_buffer(msg->du_to_cu_rrc_container);
271+
req.du_to_cu_rrc_container = byte_buffer(msg->du_to_cu_rrc_container);
263272
} else {
264273
// Assume the DU can't serve the UE, so the CU-CP should reject the UE, see TS 38.473 section 8.4.1.2.
265274
// We will forward an empty container to the RRC UE, that will trigger an RRC Reject
266-
logger.debug("du_ue_f1ap_id={}: Forwarding InitialUlRrcMessageTransfer to RRC to reject the UE. Cause: Missing DU "
275+
logger.debug("du_ue_f1ap_id={}: Forwarding InitialULRRCMessageTransfer to RRC to reject the UE. Cause: Missing DU "
267276
"to CU container",
268277
du_ue_id);
269-
ue_creation_msg.du_to_cu_rrc_container = byte_buffer{};
278+
req.du_to_cu_rrc_container = byte_buffer{};
270279
}
271-
272-
// Request the creation of a UE context in the CU-CP.
273-
const cu_cp_ue_creation_response cu_cp_resp = du_processor_notifier.on_ue_creation_request(ue_creation_msg);
280+
const ue_rrc_context_creation_response resp = du_processor_notifier.on_ue_rrc_context_creation_request(req);
274281

275282
// Remove the UE if the creation was not successful
276-
if (cu_cp_resp.ue_index == ue_index_t::invalid) {
277-
logger.warning("du_ue_f1ap_id={}: Removing the UE. UE creation failed", msg->gnb_du_ue_f1ap_id);
283+
if (resp.f1ap_rrc_notifier == nullptr) {
284+
logger.warning("du_ue_f1ap_id={}: Dropping InitialULRRCMessageTransfer. Cause: UE RRC context creation failed",
285+
msg->gnb_du_ue_f1ap_id);
278286
return;
279287
}
280288

281289
// Create UE context and store it
282-
ue_ctxt_list.add_ue(cu_cp_resp.ue_index, cu_ue_f1ap_id);
290+
ue_ctxt_list.add_ue(ue_index, cu_ue_f1ap_id);
283291
ue_ctxt_list.add_du_ue_f1ap_id(cu_ue_f1ap_id, du_ue_id);
284-
ue_ctxt_list.add_rrc_notifier(cu_cp_resp.ue_index, cu_cp_resp.f1ap_rrc_notifier);
292+
ue_ctxt_list.add_rrc_notifier(ue_index, resp.f1ap_rrc_notifier);
285293
f1ap_ue_context& ue_ctxt = ue_ctxt_list[cu_ue_f1ap_id];
286294

287295
ue_ctxt.logger.log_info("Added UE context");

lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.cpp

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,27 +98,34 @@ bool ue_context_setup_procedure::allocate_cu_ue_id()
9898
return true;
9999
}
100100

101-
bool ue_context_setup_procedure::create_ue_context(const f1ap_ue_context_setup_response& ue_ctxt_setup_resp)
101+
bool ue_context_setup_procedure::create_ue_rrc_context(const f1ap_ue_context_setup_response& ue_ctxt_setup_resp)
102102
{
103-
// Request UE creation in target cell.
104-
105-
cu_cp_ue_creation_request ue_creation_msg;
106-
ue_creation_msg.ue_index = ue_ctxt_setup_resp.ue_index;
107-
ue_creation_msg.c_rnti = ue_ctxt_setup_resp.c_rnti.value();
108-
ue_creation_msg.cgi = request.sp_cell_id;
109-
ue_creation_msg.du_to_cu_rrc_container = ue_ctxt_setup_resp.du_to_cu_rrc_info.cell_group_cfg.copy();
110-
ue_creation_msg.rrc_context = std::move(rrc_context);
111-
112-
cu_cp_ue_creation_response ue_creation_complete_msg = du_processor_notifier.on_ue_creation_request(ue_creation_msg);
113-
if (ue_creation_complete_msg.ue_index == ue_index_t::invalid) {
103+
if (not ue_ctxt_setup_resp.success or ue_ctxt_setup_resp.ue_index == ue_index_t::invalid) {
114104
logger.warning("Couldn't create UE in target cell");
115105
return false;
116106
}
117107

118-
// Add F1AP to RRC UE notifier to UE context.
119-
ue_ctxt_list.add_rrc_notifier(ue_creation_complete_msg.ue_index, ue_creation_complete_msg.f1ap_rrc_notifier);
108+
if (ue_ctxt_setup_resp.c_rnti.has_value()) {
109+
// An C-RNTI has been allocated by the DU. In such case, we need to create a new UE RRC context in the CU-CP.
110+
111+
ue_rrc_context_creation_request req;
112+
req.ue_index = ue_ctxt_setup_resp.ue_index;
113+
req.c_rnti = ue_ctxt_setup_resp.c_rnti.value();
114+
req.cgi = request.sp_cell_id;
115+
req.du_to_cu_rrc_container = ue_ctxt_setup_resp.du_to_cu_rrc_info.cell_group_cfg.copy();
116+
req.prev_context = std::move(rrc_context);
117+
118+
ue_rrc_context_creation_response resp = du_processor_notifier.on_ue_rrc_context_creation_request(req);
119+
if (resp.f1ap_rrc_notifier == nullptr) {
120+
logger.warning("Couldn't create UE RRC context in target cell");
121+
return false;
122+
}
120123

121-
logger.debug("ue={} Added RRC UE notifier", ue_creation_complete_msg.ue_index);
124+
// Add RRC notifier to F1AP UE context.
125+
ue_ctxt_list.add_rrc_notifier(req.ue_index, resp.f1ap_rrc_notifier);
126+
127+
logger.debug("ue={} Added RRC UE notifier", req.ue_index);
128+
}
122129

123130
return true;
124131
}
@@ -167,8 +174,12 @@ void ue_context_setup_procedure::create_ue_context_setup_result()
167174
ue_ctxt.ue_ids.cu_ue_f1ap_id,
168175
ue_ctxt.ue_ids.du_ue_f1ap_id);
169176

177+
// Prepare procedure response.
170178
fill_f1ap_ue_context_setup_response(response, new_ue_index, transaction_sink.response());
171-
response.success = create_ue_context(response);
179+
180+
// Create UE RRC context in CU-CP, if required.
181+
response.success = create_ue_rrc_context(response);
182+
172183
} else if (transaction_sink.failed()) {
173184
logger.debug("Received UeContextSetupFailure cause={}", get_cause_str(transaction_sink.failure()->cause));
174185
fill_f1ap_ue_context_setup_response(response, transaction_sink.failure());

lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class ue_context_setup_procedure
3838
/// Allocate F1AP CU UE ID.
3939
bool allocate_cu_ue_id();
4040

41-
bool create_ue_context(const f1ap_ue_context_setup_response& ue_ctxt_setup_resp);
41+
bool create_ue_rrc_context(const f1ap_ue_context_setup_response& ue_ctxt_setup_resp);
4242

4343
/// Send F1 UE Context Setup Request to DU.
4444
void send_ue_context_setup_request();

0 commit comments

Comments
 (0)