Read channel configuration from JSON file
Read channel information from /usr/share/ipmbbridge/ipmb-channels.json
allowing platforms to override this information.
Signed-off-by: Amithash Prasad <amithash@fb.com>
Change-Id: I161cf72840ff211c270fe56a86e6d3ebd65f170c
diff --git a/ipmbbridged.cpp b/ipmbbridged.cpp
index 72c2e1d..b37c867 100644
--- a/ipmbbridged.cpp
+++ b/ipmbbridged.cpp
@@ -18,8 +18,11 @@
#include "ipmbdefines.hpp"
#include "ipmbutils.hpp"
+#include <fstream>
+#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>
#include <tuple>
+#include <unordered_map>
extern "C" {
#include <i2c/smbus.h>
@@ -37,19 +40,10 @@
boost::asio::io_service io;
auto conn = std::make_shared<sdbusplus::asio::connection>(io);
-/**
- * @brief Channel configuration table
- * TODO : move to user configuration as JSON file
- */
-static const std::vector<IpmbChannelConfig> ipmbChannelsConfig = {
- // ME channel
- {ipmbChannelType::me, "/sys/bus/i2c/devices/5-1010/slave-mqueue",
- "/dev/i2c-5", 0x20, 0x2C}, // 8 bit addresses
- // IPMB header channel
- {ipmbChannelType::ipmb, "/sys/bus/i2c/devices/0-1010/slave-mqueue",
- "/dev/i2c-0", 0x20, 0x58}}; // 8 bit addresses
-
static std::list<IpmbChannel> ipmbChannels;
+static const std::unordered_map<std::string, ipmbChannelType>
+ ipmbChannelTypeMap = {{"me", ipmbChannelType::me},
+ {"ipmb", ipmbChannelType::ipmb}};
/**
* @brief Ipmb request class methods
@@ -615,22 +609,50 @@
std::shared_ptr<IpmbCommandFilter> commandFilter =
std::make_shared<IpmbCommandFilter>();
- for (const auto &channelConfig : ipmbChannelsConfig)
+ constexpr const char *configFilePath =
+ "/usr/share/ipmbbridge/ipmb-channels.json";
+ std::ifstream configFile(configFilePath);
+ if (!configFile.is_open())
{
- auto channel = ipmbChannels.emplace(ipmbChannels.end(), io,
- channelConfig.ipmbBmcSlaveAddress,
- channelConfig.ipmbRqSlaveAddress,
- channelConfig.type, commandFilter);
-
- if (channel->ipmbChannelInit(channelConfig.ipmbI2cSlave,
- channelConfig.ipmbI2cMaster) < 0)
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "initializeChannels: Cannot open config path");
+ return -1;
+ }
+ try
+ {
+ auto data = nlohmann::json::parse(configFile, nullptr);
+ for (const auto &channelConfig : data["channels"])
{
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "initializeChannels: channel initialization failed");
- return -1;
+ const std::string &typeConfig = channelConfig["type"];
+ const std::string &masterPath = channelConfig["master-path"];
+ const std::string &slavePath = channelConfig["slave-path"];
+ uint8_t bmcAddr = channelConfig["bmc-addr"];
+ uint8_t reqAddr = channelConfig["remote-addr"];
+ ipmbChannelType type = ipmbChannelTypeMap.at(typeConfig);
+
+ auto channel = ipmbChannels.emplace(ipmbChannels.end(), io, bmcAddr,
+ reqAddr, type, commandFilter);
+ if (channel->ipmbChannelInit(slavePath.c_str(),
+ masterPath.c_str()) < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "initializeChannels: channel initialization failed");
+ return -1;
+ }
}
}
-
+ catch (nlohmann::json::exception &e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "initializeChannels: Error parsing config file");
+ return -1;
+ }
+ catch (std::out_of_range &e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "initializeChannels: Error invalid type");
+ return -1;
+ }
return 0;
}