请解释下这个代码:int main(int argc, char *argv[])
{
std::cout << "Beerocks Controller Process Start" << std::endl;
#ifdef INCLUDE_BREAKPAD
breakpad_ExceptionHandler();
#endif
init_signals();
// Check for version query first, handle and exit if requested.
std::string module_description;
std::ofstream versionfile;
if (beerocks::version::handle_version_query(argc, argv, module_description)) {
return 0;
}
#ifdef ENABLE_NBAPI
auto amxrt = std::make_shared<beerocks::nbapi::Amxrt>();
//init amxrt and parse command line options
amxrt_cmd_line_add_option(0, 'k', "kill", no_argument, "kill the process", nullptr);
if (auto init = (amxrt->Initialize(argc, argv, handle_cmd_line_arg) != 0)) {
std::cout << "Beerocks Agent Process Failed to initalize the amxrt lib."
<< "amxrt_config_init returned : " << init << " shutting down!" << std::endl;
return init;
}
guarantee = amxrt;
(void)guarantee.use_count();
#else
int opt;
while ((opt = getopt(argc, argv, "kh")) != -1) {
switch (opt) {
case 'k':
s_kill_master = true;
break;
case 'h':
std::cout << "Usage: " << argv[0] << " -k {kill master}" << std::endl;
return 1;
default:
std::cerr << "Unknown option: " << static_cast<char>(optopt) << std::endl;
return 1;
}
}
#endif
// only kill and exit
if (s_kill_master) {
return 0;
}
// Initialize the BPL (Beerocks Platform Library)
if (beerocks::bpl::bpl_init() < 0) {
LOG(ERROR) << "Failed to initialize BPL!";
return false;
}
// read master config file
std::string master_config_file_path =
CONF_FILES_WRITABLE_PATH + std::string(BEEROCKS_CONTROLLER) +
".conf"; //search first in platform-specific default directory
beerocks::config_file::sConfigMaster beerocks_master_conf;
if (!beerocks::config_file::read_master_config_file(master_config_file_path,
beerocks_master_conf)) {
master_config_file_path = mapf::utils::get_install_path() + "config/" +
std::string(BEEROCKS_CONTROLLER) +
".conf"; // if not found, search in beerocks path
if (!beerocks::config_file::read_master_config_file(master_config_file_path,
beerocks_master_conf)) {
std::cout << "config file '" << master_config_file_path << "' args error." << std::endl;
return 1;
}
}
// read slave config file
std::string slave_config_file_path =
CONF_FILES_WRITABLE_PATH + std::string(BEEROCKS_AGENT) +
".conf"; //search first in platform-specific default directory
beerocks::config_file::sConfigSlave beerocks_slave_conf;
if (!beerocks::config_file::read_slave_config_file(slave_config_file_path,
beerocks_slave_conf)) {
slave_config_file_path = mapf::utils::get_install_path() + "config/" +
std::string(BEEROCKS_AGENT) +
".conf"; // if not found, search in beerocks path
if (!beerocks::config_file::read_slave_config_file(slave_config_file_path,
beerocks_slave_conf)) {
std::cout << "config file '" << slave_config_file_path << "' args error." << std::endl;
return 1;
}
}
std::string base_master_name = std::string(BEEROCKS_CONTROLLER);
//kill running master
beerocks::os_utils::kill_pid(beerocks_master_conf.temp_path + "pid/", base_master_name);
//init logger
beerocks::logging logger(base_master_name, beerocks_master_conf.sLog);
s_pLogger = &logger;
logger.apply_settings();
LOG(INFO) << std::endl
<< "Running " << base_master_name << " Version " << BEEROCKS_VERSION << " Build date "
<< BEEROCKS_BUILD_DATE << std::endl
<< std::endl;
beerocks::version::log_version(argc, argv);
versionfile.open(beerocks_master_conf.temp_path + "beerocks_master_version");
versionfile << BEEROCKS_VERSION << std::endl << BEEROCKS_REVISION;
versionfile.close();
// Redirect stdout / stderr
if (logger.get_log_files_enabled()) {
beerocks::os_utils::redirect_console_std(beerocks_master_conf.sLog.files_path +
base_master_name + "_std.log");
}
//write pid file
beerocks::os_utils::write_pid_file(beerocks_master_conf.temp_path, base_master_name);
std::string pid_file_path =
beerocks_master_conf.temp_path + "pid/" + base_master_name; // for file touching
// Create application event loop to wait for blocking I/O operations.
auto event_loop = std::make_shared<beerocks::EventLoopImpl>();
LOG_IF(!event_loop, FATAL) << "Unable to create event loop!";
// Create timer factory to create instances of timers.
auto timer_factory = std::make_shared<beerocks::TimerFactoryImpl>();
LOG_IF(!timer_factory, FATAL) << "Unable to create timer factory!";
// Create timer manager to help using application timers.
auto timer_manager = std::make_shared<beerocks::TimerManagerImpl>(timer_factory, event_loop);
LOG_IF(!timer_manager, FATAL) << "Unable to create timer manager!";
// Create UDS address where the server socket will listen for incoming connection requests.
std::string uds_path =
beerocks_slave_conf.temp_path + "/" + std::string(BEEROCKS_CONTROLLER_UDS);
auto uds_address = beerocks::net::UdsAddress::create_instance(uds_path);
LOG_IF(!uds_address, FATAL) << "Unable to create UDS server address!";
// Create server to exchange CMDU messages with clients connected through a UDS socket
auto cmdu_server = beerocks::CmduServerFactory::create_instance(uds_address, event_loop);
LOG_IF(!cmdu_server, FATAL) << "Unable to create CMDU server!";
beerocks::net::network_utils::iface_info bridge_info;
const auto &bridge_iface = beerocks_slave_conf.bridge_iface;
if (beerocks::net::network_utils::get_iface_info(bridge_info, bridge_iface) != 0) {
LOG(ERROR) << "Failed reading addresses from the bridge!";
return 0;
}
#ifdef ENABLE_NBAPI
auto on_action_handlers = prplmesh::controller::actions::get_actions_callback_list();
auto events_list = prplmesh::controller::actions::get_events_list();
auto funcs_list = prplmesh::controller::actions::get_func_list();
auto controller_dm_path = mapf::utils::get_install_path() + CONTROLLER_DATAMODEL_PATH;
auto amb_dm_obj = std::make_shared<beerocks::nbapi::AmbiorixImpl>(
event_loop, on_action_handlers, events_list, funcs_list);
LOG_IF(!amb_dm_obj, FATAL) << "Unable to create Ambiorix!";
LOG_IF(!amb_dm_obj->init(controller_dm_path), FATAL) << "Unable to init ambiorix object!";
#else
auto amb_dm_obj = std::make_shared<beerocks::nbapi::AmbiorixDummy>();
#endif //ENABLE_NBAPI
beerocks::bpl::set_ambiorix_impl_ptr(amb_dm_obj);
// fill master configuration
son::db::sDbMasterConfig master_conf;
fill_master_config(master_conf, beerocks_master_conf);
// Set Network.ID to the Data Model
if (!amb_dm_obj->set(DATAELEMENTS_ROOT_DM ".Network", "ID", bridge_info.mac)) {
LOG(ERROR) << "Failed to add Network.ID, mac: " << bridge_info.mac;
return false;
}
if (!amb_dm_obj->set(DATAELEMENTS_ROOT_DM ".Network", "ControllerID", bridge_info.mac)) {
LOG(ERROR) << "Failed to add Network.ControllerID, mac: " << bridge_info.mac;
return false;
}
son::db master_db(master_conf, logger, tlvf::mac_from_string(bridge_info.mac), amb_dm_obj);
#ifdef ENABLE_NBAPI
prplmesh::controller::actions::g_database = &master_db;
#endif
// The prplMesh controller needs to be configured with the SSIDs and credentials that have to
// be configured on the agents. Even though NBAPI exists to configure this, there is a lot of
// existing software out there that doesn't use it. Therefore, prplMesh should also read the
// configuration out of the legacy wireless settings.
std::list<son::wireless_utils::sBssInfoConf> wireless_settings;
if (beerocks::bpl::bpl_cfg_get_wireless_settings(wireless_settings)) {
for (const auto &configuration : wireless_settings) {
master_db.add_bss_info_configuration(configuration);
}
} else {
LOG(DEBUG) << "failed to read wireless settings";
}
#ifdef USE_PRPLMESH_WHM
std::shared_ptr<prplmesh::controller::whm::WifiManager> wifi_manager = nullptr;
if (master_conf.use_dataelements_vap_configs) {
LOG(INFO) << "use dataelements input as vap config";
} else {
LOG(INFO) << "legacy behavior: use Device.Wifi.";
wifi_manager =
std::make_shared<prplmesh::controller::whm::WifiManager>(event_loop, &master_db);
LOG_IF(!wifi_manager, FATAL) << "Unable to create controller WifiManager!";
wifi_manager->subscribe_to_bss_info_config_change();
}
#endif
// diagnostics_thread diagnostics(master_db);
// UCC server must be created in certification mode only and if a valid TCP port has been set
uint16_t port = master_db.config.ucc_listener_port;
std::unique_ptr<beerocks::UccServer> ucc_server;
if (master_db.setting_certification_mode() && (port != 0)) {
LOG(INFO) << "Certification mode enabled (listening on port " << port << ")";
// Create server to exchange UCC commands and replies with clients connected through the socket
ucc_server = beerocks::UccServerFactory::create_instance(port, event_loop);
LOG_IF(!ucc_server, FATAL) << "Unable to create UCC server!";
}
// Create broker client factory to create broker clients when requested
std::string broker_uds_path =
beerocks_slave_conf.temp_path + "/" + std::string(BEEROCKS_BROKER_UDS);
auto broker_client_factory =
beerocks::btl::create_broker_client_factory(broker_uds_path, event_loop);
LOG_IF(!broker_client_factory, FATAL) << "Unable to create broker client factory!";
son::Controller controller(master_db, std::move(broker_client_factory), std::move(ucc_server),
std::move(cmdu_server), timer_manager, event_loop);
if (!amb_dm_obj->set_current_time(DATAELEMENTS_ROOT_DM ".Network")) {
return false;
};
LOG_IF(!controller.start(), FATAL) << "Unable to start controller!";
auto touch_time_stamp_timeout = std::chrono::steady_clock::now();
while (g_running) {
// Handle signals
if (s_signal) {
handle_signal();
continue;
}
if (std::chrono::steady_clock::now() > touch_time_stamp_timeout) {
beerocks::os_utils::touch_pid_file(pid_file_path);
touch_time_stamp_timeout = std::chrono::steady_clock::now() +
std::chrono::seconds(beerocks::TOUCH_PID_TIMEOUT_SECONDS);
}
// Run application event loop and break on error.
if (event_loop->run() < 0) {
LOG(ERROR) << "Event loop failure!";
break;
}
}
s_pLogger = nullptr;
controller.stop();
beerocks::bpl::bpl_close();
return 0;
}
最新发布