2020 *
2121 */
2222
23- #include " srsran/cu_up/cu_up.h"
24- #include " srsran/cu_up/cu_up_factory.h"
2523#include " srsran/f1ap/gateways/f1c_network_server_factory.h"
2624#include " srsran/f1u/cu_up/split_connector/f1u_split_connector_factory.h"
2725#include " srsran/gateways/udp_network_gateway.h"
4442#include " srsran/support/versioning/version.h"
4543
4644#include " apps/cu/cu_appconfig_cli11_schema.h"
47- #include " apps/cu/cu_worker_manager.h"
48- #include " apps/units/cu_cp/cu_cp_builder.h"
45+ #include " apps/units/cu_cp/cu_cp_application_unit.h"
4946#include " apps/units/cu_cp/cu_cp_config_translators.h"
50- #include " apps/units/cu_cp/cu_cp_logger_registrator.h"
5147#include " apps/units/cu_cp/cu_cp_unit_config.h"
52- #include " apps/units/cu_cp/cu_cp_unit_config_cli11_schema.h"
53- #include " apps/units/cu_cp/cu_cp_unit_config_validator.h"
54- #include " apps/units/cu_cp/cu_cp_unit_logger_config.h"
5548#include " apps/units/cu_cp/pcap_factory.h"
56- #include " apps/units/cu_up/cu_up_builder.h"
57- #include " apps/units/cu_up/cu_up_logger_registrator.h"
49+ #include " apps/units/cu_up/cu_up_application_unit.h"
5850#include " apps/units/cu_up/cu_up_unit_config.h"
59- #include " apps/units/cu_up/cu_up_unit_config_cli11_schema.h"
60- #include " apps/units/cu_up/cu_up_unit_config_translators.h"
61- #include " apps/units/cu_up/cu_up_unit_config_validator.h"
62- #include " apps/units/cu_up/cu_up_wrapper.h"
6351#include " apps/units/cu_up/pcap_factory.h"
52+ #include " srsran/cu_up/cu_up.h"
6453
6554// TODO remove apps/gnb/*.h
6655#include " apps/gnb/adapters/e2_gateway_remote_connector.h"
6756#include " apps/gnb/gnb_appconfig_translators.h"
68- #include " srsran/e1ap/gateways/e1_local_connector_factory.h"
69- #include " srsran/ngap/gateways/n2_connection_client_factory.h"
7057
7158#include " apps/services/application_message_banners.h"
7259#include " apps/services/application_tracer.h"
7360#include " apps/services/buffer_pool/buffer_pool_manager.h"
7461#include " apps/services/stdin_command_dispatcher.h"
75- #include " apps/units/cu_cp/cu_cp_unit_config_yaml_writer .h"
76- #include " apps/units/cu_up/cu_up_unit_config_yaml_writer .h"
62+ #include " apps/services/worker_manager .h"
63+ #include " apps/services/worker_manager_config .h"
7764#include " cu_appconfig.h"
7865#include " cu_appconfig_validator.h"
7966#include " cu_appconfig_yaml_writer.h"
8067
68+ #include " srsran/e1ap/gateways/e1_local_connector_factory.h"
69+ #include " srsran/ngap/gateways/n2_connection_client_factory.h"
70+
8171#include < atomic>
8272#include < thread>
8373
@@ -135,9 +125,9 @@ static void initialize_log(const std::string& filename)
135125 srslog::init ();
136126}
137127
138- static void register_app_logs (const logger_appconfig& log_cfg,
139- const cu_cp_unit_logger_config& cu_cp_loggers ,
140- const cu_up_unit_logger_config& cu_up_loggers )
128+ static void register_app_logs (const logger_appconfig& log_cfg,
129+ cu_cp_application_unit& cu_cp_app_unit ,
130+ cu_up_application_unit& cu_up_app_unit )
141131{
142132 // Set log-level of app and all non-layer specific components to app level.
143133 for (const auto & id : {" ALL" , " SCTP-GW" , " IO-EPOLL" , " UDP-GW" , " PCAP" }) {
@@ -161,20 +151,24 @@ static void register_app_logs(const logger_appconfig& log_cfg,
161151 metrics_logger.set_hex_dump_max_size (log_cfg.hex_max_size );
162152
163153 // Register units logs.
164- register_cu_cp_loggers (cu_cp_loggers );
165- register_cu_up_loggers (cu_up_loggers );
154+ cu_cp_app_unit. on_loggers_registration ( );
155+ cu_up_app_unit. on_loggers_registration ( );
166156}
167157
168- // Temporary helper to create CU-UP.
169- // TODO remove
170- std::unique_ptr<srs_cu_up::cu_up_interface> app_build_cu_up (const cu_up_unit_config& unit_cfg,
171- cu_worker_manager& workers,
172- const std::string& f1u_bind_addr,
173- srs_cu_up::e1_connection_client& e1_conn_client,
174- f1u_cu_up_gateway& f1u_gateway,
175- dlt_pcap& gtpu_pcap,
176- timer_manager& timers,
177- io_broker& io_brk);
158+ static void fill_cu_worker_manager_config (worker_manager_config& config, const cu_appconfig& unit_cfg)
159+ {
160+ config.nof_low_prio_threads = unit_cfg.expert_execution_cfg .threads .non_rt_threads .nof_non_rt_threads ;
161+ config.low_prio_sched_config = unit_cfg.expert_execution_cfg .affinities .low_priority_cpu_cfg ;
162+ }
163+
164+ static void autoderive_cu_up_parameters_after_parsing (cu_up_unit_config& cu_up_cfg, const cu_cp_unit_config& cu_cp_cfg)
165+ {
166+ // If no UPF is configured, we set the UPF configuration from the CU-CP AMF configuration.
167+ if (cu_up_cfg.upf_cfg .bind_addr == " auto" ) {
168+ cu_up_cfg.upf_cfg .bind_addr = cu_cp_cfg.amf_config .amf .bind_addr ;
169+ }
170+ cu_up_cfg.upf_cfg .no_core = cu_cp_cfg.amf_config .no_core ;
171+ }
178172
179173int main (int argc, char ** argv)
180174{
@@ -202,41 +196,41 @@ int main(int argc, char** argv)
202196 cu_appconfig cu_cfg;
203197 configure_cli11_with_cu_appconfig_schema (app, cu_cfg);
204198
205- cu_cp_unit_config cu_cp_config;
206- cu_cp_config.pcap_cfg .set_default_filename (" /tmp/cu" );
207- configure_cli11_with_cu_cp_unit_config_schema (app, cu_cp_config);
199+ auto cu_cp_app_unit = create_cu_cp_application_unit (" cu" );
200+ cu_cp_app_unit->on_parsing_configuration_registration (app);
208201
209- cu_up_unit_config cu_up_config;
210- cu_up_config.pcap_cfg .set_default_filename (" /tmp/cu" );
211- configure_cli11_with_cu_up_unit_config_schema (app, cu_up_config);
202+ auto cu_up_app_unit = create_cu_up_application_unit (" cu" );
203+ cu_up_app_unit->on_parsing_configuration_registration (app);
212204
213205 // Set the callback for the app calling all the autoderivation functions.
214- app.callback ([&app, &cu_cp_config, &cu_up_config]() {
215- autoderive_cu_cp_parameters_after_parsing (app, cu_cp_config);
216- autoderive_cu_up_parameters_after_parsing (
217- cu_cp_config.amf_config .amf .bind_addr , cu_cp_config.amf_config .no_core , cu_up_config);
206+ app.callback ([&app, &cu_cp_app_unit, &cu_up_app_unit]() {
207+ cu_cp_app_unit->on_configuration_parameters_autoderivation (app);
208+
209+ autoderive_cu_up_parameters_after_parsing (cu_up_app_unit->get_cu_up_unit_config (),
210+ cu_cp_app_unit->get_cu_cp_unit_config ());
218211 });
219212
220213 // Parse arguments.
221214 CLI11_PARSE (app, argc, argv);
222215
223216 // Check the modified configuration.
224- if (!validate_cu_appconfig (cu_cfg) || !validate_cu_cp_unit_config (cu_cp_config) ||
225- !validate_cu_up_unit_config (cu_up_config)) {
217+ if (!validate_cu_appconfig (cu_cfg) ||
218+ !cu_cp_app_unit->on_configuration_validation (os_sched_affinity_bitmask::available_cpus ()) ||
219+ !cu_up_app_unit->on_configuration_validation (os_sched_affinity_bitmask::available_cpus ())) {
226220 report_error (" Invalid configuration detected.\n " );
227221 }
228222
229223 // Set up logging.
230224 initialize_log (cu_cfg.log_cfg .filename );
231- register_app_logs (cu_cfg.log_cfg , cu_cp_config. loggers , cu_up_config. loggers );
225+ register_app_logs (cu_cfg.log_cfg , *cu_cp_app_unit, *cu_up_app_unit );
232226
233227 // Log input configuration.
234228 srslog::basic_logger& config_logger = srslog::fetch_basic_logger (" CONFIG" );
235229 if (config_logger.debug .enabled ()) {
236230 YAML::Node node;
237231 fill_cu_appconfig_in_yaml_schema (node, cu_cfg);
238- fill_cu_up_config_in_yaml_schema (node, cu_up_config );
239- fill_cu_cp_config_in_yaml_schema (node, cu_cp_config );
232+ cu_cp_app_unit-> dump_config (node);
233+ cu_up_app_unit-> dump_config (node);
240234 config_logger.debug (" Input configuration (all values): \n {}" , YAML::Dump (node));
241235 } else {
242236 config_logger.info (" Input configuration (only non-default values): \n {}" , app.config_to_str (false , false ));
@@ -273,11 +267,17 @@ int main(int argc, char** argv)
273267 check_drm_kms_polling (cu_logger);
274268
275269 // Create worker manager.
276- cu_worker_manager workers{cu_cfg, cu_cp_config.pcap_cfg , cu_up_config.pcap_cfg , cu_up_config.gtpu_queue_size };
270+ worker_manager_config worker_manager_cfg;
271+ fill_cu_worker_manager_config (worker_manager_cfg, cu_cfg);
272+ cu_cp_app_unit->fill_worker_manager_config (worker_manager_cfg);
273+ cu_up_app_unit->fill_worker_manager_config (worker_manager_cfg);
274+ worker_manager workers{worker_manager_cfg};
277275
278276 // Create layer specific PCAPs.
279- cu_cp_dlt_pcaps cu_cp_dlt_pcaps = create_cu_cp_dlt_pcap (cu_cp_config.pcap_cfg , *workers.get_executor_getter ());
280- cu_up_dlt_pcaps cu_up_dlt_pcaps = create_cu_up_dlt_pcaps (cu_up_config.pcap_cfg , *workers.get_executor_getter ());
277+ cu_cp_dlt_pcaps cu_cp_dlt_pcaps =
278+ create_cu_cp_dlt_pcap (cu_cp_app_unit->get_cu_cp_unit_config ().pcap_cfg , *workers.get_executor_getter ());
279+ cu_up_dlt_pcaps cu_up_dlt_pcaps =
280+ create_cu_up_dlt_pcaps (cu_up_app_unit->get_cu_up_unit_config ().pcap_cfg , *workers.get_executor_getter ());
281281
282282 // Create IO broker.
283283 const auto & low_prio_cpu_mask = cu_cfg.expert_execution_cfg .affinities .low_priority_cpu_cfg .mask ;
@@ -306,7 +306,7 @@ int main(int argc, char** argv)
306306 std::unique_ptr<srs_cu_up::ngu_gateway> cu_f1u_gw =
307307 srs_cu_up::create_udp_ngu_gateway (cu_f1u_gw_config, *epoll_broker, *workers.cu_up_io_ul_exec );
308308 std::unique_ptr<f1u_cu_up_udp_gateway> cu_f1u_conn =
309- srs_cu_up::create_split_f1u_gw ({cu_f1u_gw. get (), cu_f1u_gtpu_demux. get () , *cu_up_dlt_pcaps.f1u , GTPU_PORT});
309+ srs_cu_up::create_split_f1u_gw ({* cu_f1u_gw, * cu_f1u_gtpu_demux, *cu_up_dlt_pcaps.f1u , GTPU_PORT});
310310
311311 // Create E1AP local connector
312312 std::unique_ptr<e1_local_connector> e1_gw =
@@ -325,18 +325,11 @@ int main(int argc, char** argv)
325325 cu_cp_dependencies.cu_cp_executor = workers.cu_cp_exec ;
326326 cu_cp_dependencies.cu_cp_e2_exec = workers.cu_cp_e2_exec ;
327327 cu_cp_dependencies.timers = cu_timers;
328-
329- // Create N2 Client Gateways.
330- cu_cp_dependencies.n2_clients .push_back (srs_cu_cp::create_n2_connection_client (generate_n2_client_config (
331- cu_cp_config.amf_config .no_core , cu_cp_config.amf_config .amf , *cu_cp_dlt_pcaps.ngap , *epoll_broker)));
332-
333- for (const auto & amf : cu_cp_config.extra_amfs ) {
334- cu_cp_dependencies.n2_clients .push_back (srs_cu_cp::create_n2_connection_client (
335- generate_n2_client_config (cu_cp_config.amf_config .no_core , amf, *cu_cp_dlt_pcaps.ngap , *epoll_broker)));
336- }
328+ cu_cp_dependencies.ngap_pcap = cu_cp_dlt_pcaps.ngap .get ();
329+ cu_cp_dependencies.broker = epoll_broker.get ();
337330
338331 // create CU-CP.
339- auto cu_cp_obj_and_cmds = build_cu_cp (cu_cp_config, cu_cp_dependencies);
332+ auto cu_cp_obj_and_cmds = cu_cp_app_unit-> create_cu_cp ( cu_cp_dependencies);
340333 srs_cu_cp::cu_cp& cu_cp_obj = *cu_cp_obj_and_cmds.unit ;
341334
342335 // Create console helper object for commands and metrics printing.
@@ -359,14 +352,15 @@ int main(int argc, char** argv)
359352 cu_f1c_gw->attach_cu_cp (cu_cp_obj.get_f1c_handler ());
360353
361354 // Create and start CU-UP
362- std::unique_ptr<srs_cu_up::cu_up_interface> cu_up_obj = app_build_cu_up (cu_up_config,
363- workers,
364- cu_cfg.nru_cfg .bind_addr ,
365- *e1_gw,
366- *cu_f1u_conn,
367- *cu_up_dlt_pcaps.n3 ,
368- *cu_timers,
369- *epoll_broker);
355+ cu_up_unit_dependencies cu_up_unit_deps;
356+ cu_up_unit_deps.workers = &workers;
357+ cu_up_unit_deps.e1ap_conn_client = e1_gw.get ();
358+ cu_up_unit_deps.f1u_gateway = cu_f1u_conn.get ();
359+ cu_up_unit_deps.gtpu_pcap = cu_up_dlt_pcaps.n3 .get ();
360+ cu_up_unit_deps.timers = cu_timers;
361+ cu_up_unit_deps.io_brk = epoll_broker.get ();
362+
363+ std::unique_ptr<srs_cu_up::cu_up_interface> cu_up_obj = cu_up_app_unit->create_cu_up_unit (cu_up_unit_deps);
370364 cu_up_obj->start ();
371365
372366 {
@@ -398,45 +392,3 @@ int main(int argc, char** argv)
398392
399393 return 0 ;
400394}
401-
402- // Temporary helper to create CU-UP.
403- // TODO remove
404- std::unique_ptr<srs_cu_up::cu_up_interface> app_build_cu_up (const cu_up_unit_config& unit_cfg,
405- cu_worker_manager& workers,
406- const std::string& f1u_bind_address,
407- srs_cu_up::e1_connection_client& e1_conn_client,
408- f1u_cu_up_gateway& f1u_gateway,
409- dlt_pcap& gtpu_pcap,
410- timer_manager& timers,
411- io_broker& io_brk)
412- {
413- srs_cu_up::cu_up_configuration config = generate_cu_up_config (unit_cfg);
414- config.ctrl_executor = workers.cu_up_ctrl_exec ;
415- config.cu_up_e2_exec = workers.cu_up_e2_exec ;
416- config.ue_exec_pool = workers.cu_up_exec_mapper .get ();
417- config.io_ul_executor = workers.cu_up_io_ul_exec ; // Optionally select separate exec for UL IO
418- config.e1ap .e1_conn_client = &e1_conn_client;
419- config.f1u_gateway = &f1u_gateway;
420- config.gtpu_pcap = >pu_pcap;
421- config.timers = &timers;
422- config.qos = generate_cu_up_qos_config (unit_cfg);
423-
424- config.net_cfg .f1u_bind_addr = f1u_bind_address; // TODO remove this parameter and make sure that the CU-UP gets the
425- // bind address directly from the gateway.
426-
427- // Create NG-U gateway.
428- std::unique_ptr<srs_cu_up::ngu_gateway> ngu_gw;
429- if (not unit_cfg.upf_cfg .no_core ) {
430- udp_network_gateway_config ngu_gw_config = {};
431- ngu_gw_config.bind_address = config.net_cfg .n3_bind_addr ;
432- ngu_gw_config.bind_port = config.net_cfg .n3_bind_port ;
433- ngu_gw_config.bind_interface = config.net_cfg .n3_bind_interface ;
434- ngu_gw_config.rx_max_mmsg = config.net_cfg .n3_rx_max_mmsg ;
435- ngu_gw = srs_cu_up::create_udp_ngu_gateway (ngu_gw_config, io_brk, *workers.cu_up_io_ul_exec );
436- } else {
437- ngu_gw = srs_cu_up::create_no_core_ngu_gateway ();
438- }
439- config.ngu_gw = ngu_gw.get ();
440-
441- return std::make_unique<cu_up_wrapper>(std::move (ngu_gw), create_cu_up (config));
442- }
0 commit comments