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
1819using 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
110180async_task<bool > du_cell_manager::start (du_cell_index_t cell_index)
0 commit comments