Skip to content

Commit f7e6698

Browse files
committed
du: support cell slice reconfiguration request
1 parent 0f9be58 commit f7e6698

27 files changed

+316
-49
lines changed

include/srsran/mac/mac_cell_manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ struct mac_cell_reconfig_request {
7272
std::optional<mac_cell_positioning_measurement_request> positioning;
7373
/// If not empty, contains the new SI PDU to be updated.
7474
std::optional<mac_cell_sys_info_pdu_update> new_si_pdu_info;
75+
/// If not empty, contains the updates to be applied to the RRM policies.
76+
std::optional<du_cell_slice_reconfig_request> slice_reconf_req;
7577
};
7678

7779
struct mac_cell_reconfig_response {

include/srsran/ran/rrm.h

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010

1111
#pragma once
1212

13+
#include "srsran/ran/du_types.h"
1314
#include "srsran/ran/plmn_identity.h"
1415
#include "srsran/ran/s_nssai.h"
1516

1617
namespace srsran {
1718

1819
/// Identifier of a RRM Policy Member.
19-
/// \remark See O-RAN.WG3.E2SM-RC-R003-v3.00 Section 8.4.3.6
2020
struct rrm_policy_member {
2121
plmn_identity plmn_id = plmn_identity::test_value();
2222
/// Single Network Slice Selection Assistance Information (S-NSSAI).
@@ -29,7 +29,7 @@ struct rrm_policy_member {
2929
};
3030

3131
struct rrm_policy_ratio_group {
32-
/// The resource type of interest for an RRM Policy
32+
/// The resource type of interest for an RRM Policy.
3333
/// \remark See 3GPP TS 28.541, Section 4.4.1 Attribute properties.
3434
enum class resource_type_t { prb, prb_ul, prb_dl };
3535
resource_type_t resource_type = resource_type_t::prb;
@@ -43,4 +43,40 @@ struct rrm_policy_ratio_group {
4343
std::optional<unsigned> ded_prb_policy_ratio;
4444
};
4545

46+
constexpr unsigned MAX_SLICE_RECONF_POLICIES = 16;
47+
48+
/// Request to reconfigure slicing policies for a given DU cell.
49+
struct du_cell_slice_reconfig_request {
50+
du_cell_index_t cell_index;
51+
struct rrm_policy_config {
52+
rrm_policy_member rrc_member;
53+
unsigned min_prb;
54+
unsigned max_prb;
55+
};
56+
static_vector<rrm_policy_config, MAX_SLICE_RECONF_POLICIES> rrm_policies;
57+
};
58+
4659
} // namespace srsran
60+
61+
namespace fmt {
62+
63+
template <>
64+
struct formatter<srsran::rrm_policy_member> {
65+
template <typename ParseContext>
66+
auto parse(ParseContext& ctx)
67+
{
68+
return ctx.begin();
69+
}
70+
71+
template <typename FormatContext>
72+
auto format(const srsran::rrm_policy_member& member, FormatContext& ctx) const
73+
{
74+
return format_to(ctx.out(),
75+
"{{PLMN={}, SST={}, SD={}}}",
76+
member.plmn_id.to_string(),
77+
member.s_nssai.sst.value(),
78+
member.s_nssai.sd.value());
79+
}
80+
};
81+
82+
} // namespace fmt

include/srsran/scheduler/scheduler_configurator.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ struct sched_cell_configuration_request_message {
109109
metrics_config metrics;
110110
};
111111

112+
/// Cell Reconfiguration Request.
113+
struct sched_cell_reconfiguration_request_message {
114+
std::optional<du_cell_slice_reconfig_request> slice_reconf_req;
115+
};
116+
112117
/// Parameters provided to the scheduler to configure the resource allocation of a specific UE.
113118
struct sched_ue_resource_alloc_config {
114119
/// Minimum and maximum PDSCH grant sizes for the given UE.
@@ -215,6 +220,9 @@ class scheduler_configurator
215220
/// \brief Deactivate a configured cell. This method has no effect if the cell is already deactivated.
216221
/// \remark This method needs to be called after the last slot_indication() call.
217222
virtual void handle_cell_deactivation_request(du_cell_index_t cell_index) = 0;
223+
224+
/// \brief Handle slice reconfiguration request of a cell.
225+
virtual void handle_slice_reconfiguration_request(const du_cell_slice_reconfig_request& msg) = 0;
218226
};
219227

220228
class scheduler_ue_configurator

lib/du/du_high/du_manager/du_cell_manager.cpp

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "converters/scheduler_configuration_helpers.h"
1414
#include "srsran/du/du_cell_config_validation.h"
1515
#include "srsran/du/du_high/du_manager/du_configurator.h"
16+
#include "srsran/ran/band_helper.h"
1617
#include "srsran/srslog/srslog.h"
1718

1819
using namespace srsran;
@@ -95,6 +96,68 @@ expected<du_cell_reconfig_result> du_cell_manager::handle_cell_reconf_request(co
9596
si_updated = true;
9697
}
9798

99+
const unsigned nof_prbs =
100+
band_helper::get_n_rbs_from_bw(MHz_to_bs_channel_bandwidth(cell_cfg.dl_carrier.carrier_bw_mhz),
101+
cell_cfg.scs_common,
102+
band_helper::get_freq_range(cell_cfg.dl_carrier.band));
103+
104+
du_cell_reconfig_result result;
105+
result.slice_reconf_req.emplace();
106+
for (const auto& rrm_policy_ratio : req.rrm_policy_ratio_list) {
107+
if (not(rrm_policy_ratio.min_prb_policy_ratio.has_value() or rrm_policy_ratio.max_prb_policy_ratio.has_value())) {
108+
continue;
109+
}
110+
111+
for (const auto& policy_member : rrm_policy_ratio.policy_members_list) {
112+
bool found = false;
113+
for (auto& policy_cfg : cell_cfg.rrm_policy_members) {
114+
if (policy_cfg.rrc_member == policy_member) {
115+
found = true;
116+
// Update the policy member configuration.
117+
unsigned min_prb_ratio =
118+
rrm_policy_ratio.min_prb_policy_ratio.has_value() ? rrm_policy_ratio.min_prb_policy_ratio.value() : 0;
119+
unsigned max_prb_ratio =
120+
rrm_policy_ratio.max_prb_policy_ratio.has_value() ? rrm_policy_ratio.max_prb_policy_ratio.value() : 100;
121+
122+
min_prb_ratio = std::clamp(min_prb_ratio, static_cast<unsigned>(0), static_cast<unsigned>(100));
123+
max_prb_ratio = std::clamp(max_prb_ratio, static_cast<unsigned>(0), static_cast<unsigned>(100));
124+
125+
const unsigned min_prb = static_cast<int>((1.0 * min_prb_ratio / 100) * nof_prbs);
126+
const unsigned max_prb = static_cast<int>((1.0 * max_prb_ratio / 100) * nof_prbs);
127+
128+
if (min_prb > max_prb) {
129+
logger.warning(
130+
"Invalid min/max PRB policy ratio for {} in cell {}: min_prb={} > max_prb={}. Skipping update.",
131+
policy_member,
132+
fmt::underlying(cell_index),
133+
min_prb,
134+
max_prb);
135+
break;
136+
}
137+
138+
if ((policy_cfg.min_prb != min_prb) or (policy_cfg.max_prb != max_prb)) {
139+
// Policy configuration has been updated.
140+
result.slice_reconf_req->rrm_policies.push_back(
141+
du_cell_slice_reconfig_request::rrm_policy_config{policy_member, min_prb, max_prb});
142+
}
143+
144+
policy_cfg.min_prb = min_prb;
145+
policy_cfg.max_prb = max_prb;
146+
break;
147+
}
148+
}
149+
if (not found) {
150+
logger.warning("No RRM policy member found for {} in cell {}", policy_member, fmt::underlying(cell_index));
151+
}
152+
153+
if (result.slice_reconf_req->rrm_policies.full()) {
154+
logger.warning("RRM policy update list is full. Discarding further updates for cell {}",
155+
fmt::underlying(cell_index));
156+
break;
157+
}
158+
}
159+
}
160+
98161
if (si_updated) {
99162
// Need to re-pack SIB1.
100163
cell.si_cfg.sib1 = asn1_packer::pack_sib1(cell_cfg);
@@ -104,7 +167,14 @@ expected<du_cell_reconfig_result> du_cell_manager::handle_cell_reconf_request(co
104167
cell.si_cfg.si_sched_cfg.version++;
105168
}
106169

107-
return du_cell_reconfig_result{cell_index, si_updated, si_updated};
170+
result.cell_index = cell_index;
171+
result.cu_notif_required = si_updated;
172+
result.sched_notif_required = si_updated;
173+
if (result.slice_reconf_req->rrm_policies.empty()) {
174+
// No RRM policy changes.
175+
result.slice_reconf_req.reset();
176+
}
177+
return result;
108178
}
109179

110180
async_task<bool> du_cell_manager::start(du_cell_index_t cell_index)

lib/du/du_high/du_manager/du_cell_manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ struct du_cell_reconfig_result {
3939
bool cu_notif_required;
4040
/// Whether the Scheduler needs to be notified about an update in the SI scheduling.
4141
bool sched_notif_required;
42+
/// Request for the MAC to change the slice configuration of the cell.
43+
std::optional<du_cell_slice_reconfig_request> slice_reconf_req;
4244
};
4345

4446
class du_cell_manager

lib/du/du_high/du_manager/du_manager_impl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ du_param_config_response du_manager_impl::handle_operator_config_request(const d
240240
// Launch config procedure.
241241
CORO_AWAIT_VALUE(auto resp, launch_async<du_param_config_procedure>(req, params, cell_mng));
242242

243-
// signal back to caller.
243+
// Signal back to caller.
244244
p.set_value(resp);
245245

246246
CORO_RETURN();

lib/du/du_high/du_manager/procedures/du_param_config_procedure.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ void du_param_config_procedure::operator()(coro_context<async_task<du_param_conf
3737
for (; next_cell_idx != changed_cells.size(); ++next_cell_idx) {
3838
// Reconfigure cell in the MAC.
3939
CORO_AWAIT_VALUE(mac_cell_reconfig_response macresp, handle_mac_cell_update(changed_cells[next_cell_idx]));
40-
if (not macresp.si_updated) {
40+
if (changed_cells[next_cell_idx].sched_notif_required and not macresp.si_updated) {
4141
resp.success = false;
4242
CORO_EARLY_RETURN(resp);
4343
}
4444
}
4545

46-
// Initiate F1AP gNB-DU Configuration Update
46+
// Initiate F1AP gNB-DU Configuration Update.
4747
CORO_AWAIT_VALUE(gnbdu_config_update_response f1resp, handle_f1_gnbdu_config_update());
4848

4949
resp.success = f1resp.result;
@@ -69,31 +69,40 @@ async_task<gnbdu_config_update_response> du_param_config_procedure::handle_f1_gn
6969
{
7070
gnbdu_config_update_request f1_req{};
7171

72-
f1_req.cells_to_mod.resize(changed_cells.size());
73-
for (unsigned i = 0, e = changed_cells.size(); i != e; ++i) {
74-
if (changed_cells[i].cu_notif_required) {
75-
const du_cell_config& cell_cfg = du_cells.get_cell_cfg(changed_cells[i].cell_index);
76-
77-
f1_req.cells_to_mod[i].cell_info = make_f1ap_du_cell_info(cell_cfg);
78-
f1_req.cells_to_mod[i].du_sys_info = make_f1ap_du_sys_info(cell_cfg);
72+
f1_req.cells_to_mod.reserve(changed_cells.size());
73+
for (const auto& changed_cell : changed_cells) {
74+
if (changed_cell.cu_notif_required) {
75+
const du_cell_config& cell_cfg = du_cells.get_cell_cfg(changed_cell.cell_index);
76+
auto& cell = f1_req.cells_to_mod.emplace_back();
77+
cell.cell_info = make_f1ap_du_cell_info(cell_cfg);
78+
cell.du_sys_info = make_f1ap_du_sys_info(cell_cfg);
7979
}
8080
}
8181

82+
if (f1_req.cells_to_mod.empty()) {
83+
return launch_no_op_task(gnbdu_config_update_response{true});
84+
}
85+
8286
return du_params.f1ap.conn_mng.handle_du_config_update(f1_req);
8387
}
8488

8589
async_task<mac_cell_reconfig_response>
8690
du_param_config_procedure::handle_mac_cell_update(const du_cell_reconfig_result& changed_cell)
8791
{
88-
if (not changed_cell.sched_notif_required) {
89-
// TODO: Support changes that do not require SI scheduling config update.
92+
if (not changed_cell.sched_notif_required and not changed_cell.slice_reconf_req.has_value()) {
9093
return launch_no_op_task(mac_cell_reconfig_response{});
9194
}
9295

9396
mac_cell_reconfig_request req;
9497

95-
// Update SIB1 and SI message content.
96-
req.new_sys_info = du_cells.get_sys_info(changed_cell.cell_index);
98+
if (changed_cell.sched_notif_required) {
99+
// Update SIB1 and SI message content.
100+
req.new_sys_info = du_cells.get_sys_info(changed_cell.cell_index);
101+
}
102+
103+
if (changed_cell.slice_reconf_req.has_value()) {
104+
req.slice_reconf_req.emplace(changed_cell.slice_reconf_req.value());
105+
}
97106

98107
return du_params.mac.cell_mng.get_cell_controller(changed_cell.cell_index).reconfigure(req);
99108
}

lib/e2/e2sm/e2sm_ccc/e2sm_ccc_control_action_du_executor.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -294,15 +294,11 @@ e2sm_ccc_control_o_rrm_policy_ratio_executor::execute_ric_control_action(const e
294294
// Log received control request.
295295
log_du_config_request(logger, du_ctrl_config_req);
296296

297-
return launch_async(
298-
[&req, ctrl_config = std::move(du_ctrl_config_req)](coro_context<async_task<e2sm_ric_control_response>>& ctx) {
299-
CORO_BEGIN(ctx);
300-
srs_du::du_param_config_response ctrl_response;
301-
// TODO: remove success = true, add this to the capture list above, and uncomment when RRM Policy
302-
// reconfiguration handling is implemented in DU.
303-
ctrl_response.success = true;
304-
// ctrl_response = du_param_configurator.handle_operator_config_request(ctrl_config);
305-
e2sm_ric_control_response e2_resp = convert_to_e2sm_response(req, ctrl_config, ctrl_response);
306-
CORO_RETURN(e2_resp);
307-
});
297+
return launch_async([this, &req, ctrl_config = std::move(du_ctrl_config_req)](
298+
coro_context<async_task<e2sm_ric_control_response>>& ctx) {
299+
CORO_BEGIN(ctx);
300+
srs_du::du_param_config_response ctrl_response = du_param_configurator.handle_operator_config_request(ctrl_config);
301+
e2sm_ric_control_response e2_resp = convert_to_e2sm_response(req, ctrl_config, ctrl_response);
302+
CORO_RETURN(e2_resp);
303+
});
308304
}

lib/mac/mac_dl/mac_cell_processor.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,19 @@ async_task<mac_cell_reconfig_response> mac_cell_processor::reconfigure(const mac
179179
resp.si_pdus_enqueued = true;
180180
}
181181

182+
if (request.slice_reconf_req.has_value()) {
183+
// Change to respective DL cell executor context.
184+
CORO_AWAIT(execute_on_blocking(cell_exec, timers));
185+
186+
{
187+
SRSRAN_RTSAN_SCOPED_ENABLER;
188+
sched.handle_slice_reconfiguration_request(request.slice_reconf_req.value());
189+
}
190+
191+
// Change back to CTRL executor context.
192+
CORO_AWAIT(execute_on_blocking(ctrl_exec, timers));
193+
}
194+
182195
CORO_RETURN(resp);
183196
});
184197
}

lib/mac/mac_dl/mac_scheduler_cell_info_handler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ class mac_scheduler_cell_info_handler : public mac_ue_control_information_handle
5858
virtual async_task<mac_cell_positioning_measurement_response>
5959
handle_positioning_measurement_request(du_cell_index_t cell_index,
6060
const mac_cell_positioning_measurement_request& req) = 0;
61+
62+
/// \brief Handle request to update the slice configuration of a cell.
63+
/// \param[in] cell_index Index of the cell for which the measurement is directed.
64+
/// \param[in] req Request to update the RRM policies.
65+
virtual void handle_slice_reconfiguration_request(const du_cell_slice_reconfig_request& req) = 0;
6166
};
6267

6368
} // namespace srsran

0 commit comments

Comments
 (0)