Agent: Add amxrt support for agent DM

Signed-off-by: Volodymyr Pavlenko <v.pavlenko@inango-systems.com>
This commit is contained in:
Volodymyr Pavlenko
2025-03-14 14:50:25 +02:00
committed by Frederik Van Bogaert
parent e6963700fc
commit 844fa8c3e7
16 changed files with 204 additions and 139 deletions

1
.gitignore vendored
View File

@@ -21,4 +21,3 @@ ipkg-*/
/rdk
.dccache
.vscode/**
agent/src/beerocks/slave/nbapi/odl/*.odl

View File

@@ -22,7 +22,7 @@ function(process_root_dm ROOT_DM_VAR ROOT_DM_LITERAL_VAR ROOT_DM_HEADER_VAR ROOT
set(footer "")
foreach(object IN LISTS ROOT_DM_SPLIT)
set(header "${header}${indent}object ${object} {\n")
set(header "${header}${indent}%persistent object ${object} {\n")
set(footer "}\n${footer}")
set(indent " ${indent}")
endforeach()
@@ -54,14 +54,6 @@ process_root_dm(DATAELEMENTS_ROOT_DM DATAELEMENTS_ROOT_DM_literal DATAELEMENTS_R
process_root_dm(CONTROLLER_ROOT_DM CONTROLLER_ROOT_DM_literal CONTROLLER_ROOT_DM_Header CONTROLLER_ROOT_DM_Footer)
process_root_dm(AGENT_ROOT_DM AGENT_ROOT_DM_literal AGENT_ROOT_DM_Header AGENT_ROOT_DM_Footer)
message(STATUS "VOLODYMYR DATAELEMENTS_ROOT_DM: ${DATAELEMENTS_ROOT_DM}")
message(STATUS "VOLODYMYR DATAELEMENTS_ROOT_DM_Header:\n${DATAELEMENTS_ROOT_DM_Header}")
message(STATUS "VOLODYMYR DATAELEMENTS_ROOT_DM_Footer:\n${DATAELEMENTS_ROOT_DM_Footer}")
message(STATUS "VOLODYMYR CONTROLLER_ROOT_DM: ${CONTROLLER_ROOT_DM}")
message(STATUS "VOLODYMYR CONTROLLER_ROOT_DM_Header:\n${CONTROLLER_ROOT_DM_Header}")
message(STATUS "VOLODYMYR CONTROLLER_ROOT_DM_Footer:\n${CONTROLLER_ROOT_DM_Footer}")
## Build options

View File

@@ -49,7 +49,7 @@ static std::shared_ptr<beerocks::nbapi::Amxrt> guarantee = nullptr;
#endif // AMBIORIX_BUS_URI
#ifndef AGENT_DATAMODEL_PATH
#define AGENT_DATAMODEL_PATH "config/odl/agent.odl"
#define AGENT_DATAMODEL_PATH "config/odl/slave_config.odl"
#endif // AGENT_DATAMODEL_PATH
#endif
@@ -353,7 +353,6 @@ static int run_beerocks_slave(beerocks::config_file::sConfigSlave &beerocks_slav
slave_ap_ifaces.insert(elm.second);
}
}
// 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!";
@@ -416,7 +415,6 @@ static int run_beerocks_slave(beerocks::config_file::sConfigSlave &beerocks_slav
beerocks::PlatformManager platform_manager(beerocks_slave_conf, interfaces_map, *agent_logger,
std::move(platform_manager_cmdu_server),
timer_manager, event_loop);
// Start platform manager
LOG_IF(!platform_manager.start(), FATAL) << "Unable to start platform manager!";
@@ -476,7 +474,6 @@ static int run_beerocks_slave(beerocks::config_file::sConfigSlave &beerocks_slav
break;
}
}
agent->stop();
LOG(DEBUG) << "backhaul_manager.stop()";
@@ -523,17 +520,17 @@ static void remove_residual_agent_files(const std::string &path, const std::stri
*
* @return management mode in agent database
*/
static uint8_t read_management_mode()
{
auto db = beerocks::AgentDB::get();
auto management_mode = beerocks::bpl::cfg_get_management_mode();
// static uint8_t read_management_mode()
// {
// auto db = beerocks::AgentDB::get();
// auto management_mode = beerocks::bpl::cfg_get_management_mode();
if (management_mode >= 0) {
db->device_conf.management_mode = management_mode;
}
// if (management_mode >= 0) {
// db->device_conf.management_mode = management_mode;
// }
return db->device_conf.management_mode;
}
// return db->device_conf.management_mode;
// }
int main(int argc, char *argv[])
{
@@ -546,19 +543,16 @@ int main(int argc, char *argv[])
if (beerocks::version::handle_version_query(argc, argv, module_description)) {
return 0;
}
//get command line options
if (!parse_arguments(argc, argv)) {
std::cout << "Usage: " << argv[0] << std::endl;
return 1;
}
// Initialize the BPL (Beerocks Platform Library)
if (beerocks::bpl::bpl_init() < 0) {
LOG(ERROR) << "Failed to initialize BPL!";
return false;
}
// read slave config file
std::string slave_config_file_path =
CONF_FILES_WRITABLE_PATH + std::string(BEEROCKS_AGENT) +
@@ -575,7 +569,6 @@ int main(int argc, char *argv[])
return 1;
}
}
// beerocks system hang tester
if (beerocks_slave_conf.enable_system_hang_test == "1") {
@@ -585,7 +578,6 @@ int main(int argc, char *argv[])
return system_hang_test(beerocks_slave_conf, argc, argv);
}
}
// Create unordered_map of interfaces.
// This map contains all the radios that we expect to be there.
// We don't go to operational until the slaves for these interfaces are operational.
@@ -593,48 +585,39 @@ int main(int argc, char *argv[])
// Controller only mode does not take care of interfaces
// TODO: MaxLinear DHCP monitoring may need to fill interfaces (PPM-1777)
if (read_management_mode() != BPL_MGMT_MODE_MULTIAP_CONTROLLER) {
beerocks::bpl::BPL_WLAN_IFACE interfaces[beerocks::MAX_RADIOS_PER_AGENT] = {0};
int num_of_interfaces = beerocks::MAX_RADIOS_PER_AGENT;
if (beerocks::bpl::cfg_get_all_prplmesh_wifi_interfaces(interfaces, &num_of_interfaces)) {
std::cout << "ERROR: Failed to read interfaces map" << std::endl;
return 1;
beerocks::bpl::BPL_WLAN_IFACE interfaces[beerocks::MAX_RADIOS_PER_AGENT] = {0};
int num_of_interfaces = beerocks::MAX_RADIOS_PER_AGENT;
if (beerocks::bpl::cfg_get_all_prplmesh_wifi_interfaces(interfaces, &num_of_interfaces)) {
std::cout << "ERROR: Failed to read interfaces map" << std::endl;
return 1;
}
std::string mandatory_interfaces;
std::vector<std::string> mandatory_interfaces_vec;
// Read the mandatory interfaces list from config and parse it if not empty
if (beerocks::bpl::bpl_cfg_get_mandatory_interfaces(mandatory_interfaces)) {
if (!mandatory_interfaces.empty()) {
mandatory_interfaces_vec = beerocks::string_utils::str_split(mandatory_interfaces, ',');
}
std::string mandatory_interfaces;
std::vector<std::string> mandatory_interfaces_vec;
// Read the mandatory interfaces list from config and parse it if not empty
if (beerocks::bpl::bpl_cfg_get_mandatory_interfaces(mandatory_interfaces)) {
if (!mandatory_interfaces.empty()) {
mandatory_interfaces_vec =
beerocks::string_utils::str_split(mandatory_interfaces, ',');
}
}
for (int i = 0; i < num_of_interfaces; i++) {
// If interface is mandatory
if (std::find(mandatory_interfaces_vec.begin(), mandatory_interfaces_vec.end(),
interfaces[i].ifname) != mandatory_interfaces_vec.end()) {
interfaces_map[interfaces[i].radio_num] = std::string(interfaces[i].ifname);
} else if (beerocks::net::network_utils::linux_iface_exists(interfaces[i].ifname)) {
// if interface is not mandatory and exists
interfaces_map[interfaces[i].radio_num] = std::string(interfaces[i].ifname);
}
for (int i = 0; i < num_of_interfaces; i++) {
// If interface is mandatory
if (std::find(mandatory_interfaces_vec.begin(), mandatory_interfaces_vec.end(),
interfaces[i].ifname) != mandatory_interfaces_vec.end()) {
interfaces_map[interfaces[i].radio_num] = std::string(interfaces[i].ifname);
} else if (beerocks::net::network_utils::linux_iface_exists(interfaces[i].ifname)) {
// if interface is not mandatory and exists
interfaces_map[interfaces[i].radio_num] = std::string(interfaces[i].ifname);
}
}
}
if (interfaces_map.empty()) {
std::cout << "INFO: No radio interfaces are available" << std::endl;
return 0;
}
}
// killall running slave
beerocks::os_utils::kill_pid(beerocks_slave_conf.temp_path + "pid/",
std::string(BEEROCKS_AGENT));
// Remove any residual agent files not cleared by previous instance
remove_residual_agent_files(beerocks_slave_conf.temp_path, std::string(BEEROCKS_AGENT));
// backhaul/platform manager slave
return run_beerocks_slave(beerocks_slave_conf, interfaces_map, argc, argv);
// killall running slave
beerocks::os_utils::kill_pid(beerocks_slave_conf.temp_path + "pid/",
std::string(BEEROCKS_AGENT));
// Remove any residual agent files not cleared by previous instance
remove_residual_agent_files(beerocks_slave_conf.temp_path, std::string(BEEROCKS_AGENT));
// backhaul/platform manager slave
return run_beerocks_slave(beerocks_slave_conf, interfaces_map, argc, argv);
}

View File

@@ -6,24 +6,29 @@
# See LICENSE file for more details.
# Set agent data model path
set(DATAMODELS_PATH ${CMAKE_CURRENT_SOURCE_DIR}/odl)
set(DATAMODELS_PATH ${CMAKE_CURRENT_BINARY_DIR}/odl)
message(STATUS "Using CMake version: ${CMAKE_VERSION}")
message(STATUS "Test agent data model:")
# configure_file_odl func
include("${CMAKE_SOURCE_DIR}/cmake/ConfigureOdl.cmake")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/odl/agent.odl.in"
"${CMAKE_CURRENT_SOURCE_DIR}/odl/agent.odl"
)
# Process all .odl.in files dynamically
file(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/odl/*.odl.in")
foreach(file ${files})
configure_file_odl(${file})
endforeach()
# Parse agent.odl file
execute_process(COMMAND amxo-cg ${DATAMODELS_PATH}/agent.odl RESULT_VARIABLE DATAMODEL_PARSE_RESULT)
message(STATUS "Parsing ODL using amxo: slave_config.odl")
execute_process(COMMAND amxo-cg ${DATAMODELS_PATH}/slave_config.odl --no-warnings RESULT_VARIABLE DATAMODEL_PARSE_RESULT)
# If parser find errors - generate FATAL_ERROR
# Check for parser errors
if(${DATAMODEL_PARSE_RESULT})
message(FATAL_ERROR "Failed to parse agent data model!")
endif()
message(STATUS "Agent data model tested successfully!")
install(DIRECTORY ${DATAMODELS_PATH} DESTINATION config)
file(COPY ${DATAMODELS_PATH} DESTINATION "${CMAKE_MULTIAP_OUTPUT_DIRECTORY}/config/odl")
message(STATUS "Agent data model tested successfully!")
if(IS_DIRECTORY ${DATAMODELS_PATH}/defaults.d)
install(DIRECTORY ${DATAMODELS_PATH}/defaults.d DESTINATION config/odl)
endif()

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-2-Clause-Patent
*
* SPDX-FileCopyrightText: 2021 the prplMesh contributors (see AUTHORS.md)
* SPDX-FileCopyrightText: 2025 the prplMesh contributors (see AUTHORS.md)
*
* This code is subject to the terms of the BSD+Patent license.
* See LICENSE file for more details.
@@ -21,7 +21,7 @@
default "Agent";
on action validate call check_enum [
"Agent",
"Controller",
"Controller",
"Controller+Agent"
];
}

View File

@@ -0,0 +1,54 @@
/* SPDX-License-Identifier: BSD-2-Clause-Patent
*
* SPDX-FileCopyrightText: 2025 the prplMesh contributors (see AUTHORS.md)
*
* This code is subject to the terms of the BSD+Patent license.
* See LICENSE file for more details.
*/
#!/usr/bin/amxrt
%config {
name = "agent";
agent = {
mod-dir = "$@@{prefix}$@@{plugin-dir}/prplmesh/modules",
external-mod-dir = "$@@{prefix}$@@{plugin-dir}/modules"
};
silent = false;
import-dbg = true;
dm-eventing-enabled = true;
storage-path = "/opt/prplmesh/share";
storage-type = "odl";
odl = {
dm-load = true,
dm-save = true,
dm-save-on-changed = true,
dm-save-delay = 1000,
directory = "$@@{storage-path}/odl"
};
cfg-dir = "/etc/amx";
include-dirs = [
".",
"$@@{cfg-dir}/prplmesh",
"$@@{cfg-dir}/modules",
"/opt/prplmesh/config/odl"
];
import-dirs = [
".",
"$@@{prefix}$@@{plugin-dir}/prplmesh",
"$@@{prefix}$@@{plugin-dir}/modules",
"$@@{prefix}/usr/lib/amx/prplmesh",
"$@@{prefix}/usr/lib/amx/modules"
];
//main files
definition_file = "agent.odl";
//persistent storage
pcm_svc_config = {
"Objects" = "@AGENT_ROOT_DM_Header@"
};
}
include "$@@{definition_file}";
#include "mod_pcm_svc.odl";
import "mod-dmext.so";

26
cmake/ConfigureOdl.cmake Normal file
View File

@@ -0,0 +1,26 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# SPDX-FileCopyrightText: 2025 the prplMesh contributors (see AUTHORS.md)
#
# This code is subject to the terms of the BSD+Patent license.
# See LICENSE file for more details.
# The `configure_file_odl` function preprocesses .odl.in files.
# It temporarily replaces ${} to avoid its parsing by `configure_file`.
function(configure_file_odl odl_file_input)
get_filename_component(input_directory ${odl_file_input} DIRECTORY)
get_filename_component(input_filename ${odl_file_input} NAME)
string(REGEX REPLACE "\\.[^.]*$" "" barename ${input_filename})
file(RELATIVE_PATH relative_path ${CMAKE_CURRENT_SOURCE_DIR} ${input_directory})
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${relative_path}")
# Replace ${} with $@@{} to prevent parsing by `configure_file`.
execute_process(COMMAND bash "-c" "sed -r -i 's/\\$\\{([^}]*)\\}/\\$@@\\{\\1\\}/g' ${odl_file_input}")
message(STATUS "Generating ODL file: ${barename}")
configure_file(${odl_file_input} "${CMAKE_CURRENT_BINARY_DIR}/${relative_path}/${barename}")
# Revert $@@{} back to ${} after `configure_file`.
execute_process(COMMAND bash "-c" "sed -r -i 's/\\$@@\\{([^}]*)\\}/\\$\\{\\1\\}/g' ${CMAKE_CURRENT_BINARY_DIR}/${relative_path}/${barename}")
endfunction()

View File

@@ -9,32 +9,8 @@
set(DATAMODELS_PATH ${CMAKE_CURRENT_BINARY_DIR}/odl)
message(STATUS "Using CMake version : " ${CMAKE_VERSION})
# The `configure_file_odl` function preprocesses .odl.in files.
# It temporarily replaces ${} to avoid its parsing by `configure_file`.
function(configure_file_odl odl_file_input)
# Extract the directory and filename
get_filename_component(input_directory ${odl_file_input} DIRECTORY)
get_filename_component(input_filename ${odl_file_input} NAME)
# Get the filename without extension
string(REGEX REPLACE "\\.[^.]*$" "" barename ${input_filename})
# Get the relative path from the source directory to the input directory
file(RELATIVE_PATH relative_path ${CMAKE_CURRENT_SOURCE_DIR} ${input_directory})
# Ensure the output directory exists
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${relative_path}")
# Replace ${} with $@@{} to prevent parsing by `configure_file`.
execute_process(COMMAND bash "-c" "sed -r -i 's/\\$\\{([^}]*)\\}/\\$@@\\{\\1\\}/g' ${odl_file_input}")
message(STATUS "${BoldCyan}Generating odl file${ColourReset} : " ${barename})
configure_file(${odl_file_input} "${CMAKE_CURRENT_BINARY_DIR}/${relative_path}/${barename}")
# Revert $@@{} back to ${} after `configure_file`.
execute_process(COMMAND bash "-c" "sed -r -i 's/\\$@@\\{([^}]*)\\}/\\$\\{\\1\\}/g' ${CMAKE_CURRENT_BINARY_DIR}/${relative_path}/${barename}")
endfunction()
# configure_file_odl func
include("${CMAKE_SOURCE_DIR}/cmake/ConfigureOdl.cmake")
#search for all available .odl.in files in the odl folder and parse them
file(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/odl/*.odl.in")
@@ -47,9 +23,9 @@ foreach(file ${files})
configure_file_odl(${file})
endforeach()
# Parse prplmesh_definitions.odl file
message(STATUS "${BoldYellow}Parse odl using amxo${ColourReset} : prplmesh.odl")
execute_process(COMMAND amxo-cg ${DATAMODELS_PATH}/prplmesh.odl --no-warnings RESULT_VARIABLE DATAMODEL_PARSE_RESULT)
# Parse master_config.odl file
message(STATUS "${BoldYellow}Parse odl using amxo${ColourReset} : master_config.odl")
execute_process(COMMAND amxo-cg ${DATAMODELS_PATH}/master_config.odl --no-warnings RESULT_VARIABLE DATAMODEL_PARSE_RESULT)
# If parser find errors - generate FATAL_ERROR
if(${DATAMODEL_PARSE_RESULT})

View File

@@ -223,6 +223,7 @@
/* Interval (in seconds) for statistics polling task */
%persistent uint32 StatisticsPollingRateSec {
default 1;
on action validate call check_range [1, 10000];
}

View File

@@ -9,15 +9,15 @@
#!/usr/bin/amxrt
%config {
name = "prplmesh";
prplmesh = {
mod-dir = "$@@{prefix}$@@{plugin-dir}/$@@{name}/modules",
name = "controller";
controller = {
mod-dir = "$@@{prefix}$@@{plugin-dir}/prplmesh/modules",
external-mod-dir = "$@@{prefix}$@@{plugin-dir}/modules"
};
silent = false;
import-dbg = true;
dm-eventing-enabled = true;
storage-path = "/opt/$@@{name}/share";
storage-path = "/opt/prplmesh/share";
storage-type = "odl";
odl = {
dm-load = true,
@@ -30,15 +30,15 @@
cfg-dir = "/etc/amx";
include-dirs = [
".",
"$@@{cfg-dir}/$@@{name}",
"$@@{cfg-dir}/prplmesh",
"$@@{cfg-dir}/modules",
"/opt/prplmesh/config/odl"
];
import-dirs = [
".",
"$@@{prefix}$@@{plugin-dir}/$@@{name}",
"$@@{prefix}$@@{plugin-dir}/prplmesh",
"$@@{prefix}$@@{plugin-dir}/modules",
"$@@{prefix}/usr/lib/amx/$@@{name}",
"$@@{prefix}/usr/lib/amx/prplmesh",
"$@@{prefix}/usr/lib/amx/modules"
];
//main files
@@ -46,7 +46,7 @@
//persistent storage
pcm_svc_config = {
"Objects" = "@CONTROLLER_ROOT_DM_Header@"
"Objects" = "@AGENT_ROOT_DM_Header@"
};
}
include "$@@{definition_file}";

View File

@@ -53,7 +53,7 @@ static std::shared_ptr<beerocks::nbapi::Amxrt> guarantee = nullptr;
#endif // AMBIORIX_BUS_URI
#ifndef CONTROLLER_DATAMODEL_PATH
#define CONTROLLER_DATAMODEL_PATH "config/odl/prplmesh.odl"
#define CONTROLLER_DATAMODEL_PATH "config/odl/master_config.odl"
#endif
#endif //#else // ENABLE_NBAPI

View File

@@ -91,7 +91,7 @@ if (TARGET_PLATFORM STREQUAL "openwrt")
${MODULE_PATH}/arp/linux/*.c*
${MODULE_PATH}/dhcp/luci_rpc/*.c*
${MODULE_PATH}/db/uci/*.c*
${MODULE_PATH}/cfg/uci/*.c*
${MODULE_PATH}/cfg/dm/*.c*
${MODULE_PATH}/cfg/vendor/*.c*
${MODULE_PATH}/common/uci/*.c*
${MODULE_PATH}/board/system_ubus/*.c*

View File

@@ -6,34 +6,39 @@
* See LICENSE file for more details.
*/
#include "bpl_cfg.h"
#include <bpl/bpl_cfg.h>
#include "bpl_cfg_amx_wrapper.h"
#include <mapf/common/logger.h>
#include "bpl_cfg_amx_helper.h"
namespace beerocks {
namespace bpl {
int cfg_get_hostap_iface_steer_vaps(int32_t radio_num,
char hostap_iface_steer_vaps[BPL_LOAD_STEER_ON_VAPS_LEN])
int cfg_is_enabled() { return 1; }
int cfg_set_onboarding(int enable) { return 0; }
int cfg_is_master()
{
return 0;
switch (cfg_get_management_mode()) {
case BPL_MGMT_MODE_MULTIAP_CONTROLLER_AGENT:
return 1;
case BPL_MGMT_MODE_MULTIAP_CONTROLLER:
return 1;
case BPL_MGMT_MODE_MULTIAP_AGENT:
return 0;
default:
return -1;
}
}
int cfg_is_enabled() { return 0; }
int cfg_is_master() { return 0; }
int cfg_get_management_mode()
{
int management_mode{BPL_MGMT_MODE_MULTIAP_AGENT}; // Agent by default
auto agent_dm = get_agent_dm();
if (!agent_dm) {
MAPF_ERR("cfg_get_management_mode: agent_dm does not exist");
}
std::string management_mode_str{};
agent_dm->read_child(management_mode_str, "ManagementMode");
cfg_get_management_mode(mode);
if (management_mode_str == "Controller+Agent") {
management_mode = BPL_MGMT_MODE_MULTIAP_CONTROLLER_AGENT;
@@ -48,7 +53,19 @@ int cfg_get_management_mode()
return management_mode;
}
int cfg_get_management_mode(std::string &mode) { return 0; }
int cfg_get_management_mode(std::string &mode)
{
auto agent_dm = get_agent_dm();
if (!agent_dm) {
MAPF_ERR("cfg_get_management_mode: agent_dm does not exist");
}
agent_dm->read_child(mode, "ManagementMode");
MAPF_INFO("cfg_get_management_mode: " + management_mode_str);
return 0;
}
int cfg_get_operating_mode() { return 0; }
@@ -63,7 +80,7 @@ int cfg_get_certification_mode()
agent_dm->read_child(certification_mode, "CertificationMode");
return management_mode;
return certification_mode;
}
int cfg_get_load_steer_on_vaps(int num_of_interfaces,
@@ -230,7 +247,11 @@ bool cfg_set_unsuccessful_assoc_max_reporting_rate(int &unsuccessful_assoc_max_r
bool bpl_get_lan_interfaces(std::vector<std::string> &lan_iface_list) { return false; }
bool bpl_cfg_get_backhaul_wire_iface(std::string &iface) { return false; }
bool bpl_cfg_get_backhaul_wire_iface(std::string &iface)
{
iface = "wan";
return true;
}
bool cfg_get_roaming_hysteresis_percent_bonus(int &roaming_hysteresis_percent_bonus)
{

View File

@@ -9,10 +9,12 @@
#ifndef _BPL_CFG_AMX_HELPER_H_
#define _BPL_CFG_AMX_HELPER_H_
#include "ambiorix_impl.h"
#include "bpl_cfg_pwhm.h"
#include <ambiorix_variant.h>
using beerocks::wbapi::AmbiorixVariantSmartPtr;
namespace beerocks {
namespace bpl {

View File

@@ -372,6 +372,12 @@ int cfg_get_hostap_iface(int32_t radio_num, char hostap_iface[BPL_IFNAME_LEN])
return RETURN_ERR;
}
int cfg_get_hostap_iface_steer_vaps(int32_t radio_num,
char hostap_iface_steer_vaps[BPL_LOAD_STEER_ON_VAPS_LEN])
{
return 0;
}
bool bpl_cfg_get_monitored_BSSs_by_radio_iface(const std::string &iface,
std::set<std::string> &monitored_BSSs)
{

View File

@@ -373,7 +373,7 @@ int cfg_is_master();
int cfg_get_management_mode();
/**
* Returns the current management mode configuration
* @param reference to set the current management mode str
*
* @returns <0 on error
*/