diff options
author | Ed Tanous <ed.tanous@intel.com> | 2018-09-05 18:30:59 +0300 |
---|---|---|
committer | Ed Tanous <ed.tanous@intel.com> | 2018-09-05 18:44:12 +0300 |
commit | 1abe55ef9844afcddcab9d862ae06118f3a2390c (patch) | |
tree | d0b5fcfd0b1cd679a8995af3eb0b6d31b368380e /redfish-core/lib/sensors.hpp | |
parent | a38b0b206300c792979b900f506b85e535f5708a (diff) | |
download | bmcweb-1abe55ef9844afcddcab9d862ae06118f3a2390c.tar.xz |
Move to clang-format-6.0
This commit moves the codebase to the lastest clang-format file from
upstream, as well as clang-format-6.0.
Change-Id: Ice8313468097c0c42317fbb9e10ddf036e8cff4c
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
Diffstat (limited to 'redfish-core/lib/sensors.hpp')
-rw-r--r-- | redfish-core/lib/sensors.hpp | 788 |
1 files changed, 442 insertions, 346 deletions
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp index 7f9fa684bc..c390cd7908 100644 --- a/redfish-core/lib/sensors.hpp +++ b/redfish-core/lib/sensors.hpp @@ -16,13 +16,15 @@ #pragma once #include <math.h> -#include <dbus_singleton.hpp> + #include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/split.hpp> #include <boost/container/flat_map.hpp> #include <boost/range/algorithm/replace_copy_if.hpp> +#include <dbus_singleton.hpp> -namespace redfish { +namespace redfish +{ constexpr const char* dbusSensorPrefix = "/xyz/openbmc_project/sensors/"; @@ -41,32 +43,38 @@ using ManagedObjectsVectorType = std::vector<std::pair< * SensorsAsyncResp * Gathers data needed for response processing after async calls are done */ -class SensorsAsyncResp { - public: - SensorsAsyncResp(crow::Response& response, const std::string& chassisId, - const std::initializer_list<const char*> types) - : res(response), chassisId(chassisId), types(types) { - res.jsonValue["@odata.id"] = - "/redfish/v1/Chassis/" + chassisId + "/Thermal"; - } - - ~SensorsAsyncResp() { - if (res.result() == boost::beast::http::status::internal_server_error) { - // Reset the json object to clear out any data that made it in before the - // error happened - // todo(ed) handle error condition with proper code - res.jsonValue = nlohmann::json::object(); +class SensorsAsyncResp +{ + public: + SensorsAsyncResp(crow::Response& response, const std::string& chassisId, + const std::initializer_list<const char*> types) : + res(response), + chassisId(chassisId), types(types) + { + res.jsonValue["@odata.id"] = + "/redfish/v1/Chassis/" + chassisId + "/Thermal"; } - res.end(); - } - void setErrorStatus() { - res.result(boost::beast::http::status::internal_server_error); - } + ~SensorsAsyncResp() + { + if (res.result() == boost::beast::http::status::internal_server_error) + { + // Reset the json object to clear out any data that made it in + // before the error happened todo(ed) handle error condition with + // proper code + res.jsonValue = nlohmann::json::object(); + } + res.end(); + } + + void setErrorStatus() + { + res.result(boost::beast::http::status::internal_server_error); + } - crow::Response& res; - std::string chassisId{}; - const std::vector<const char*> types; + crow::Response& res; + std::string chassisId{}; + const std::vector<const char*> types; }; /** @@ -78,70 +86,84 @@ class SensorsAsyncResp { template <typename Callback> void getConnections(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp, const boost::container::flat_set<std::string>& sensorNames, - Callback&& callback) { - BMCWEB_LOG_DEBUG << "getConnections enter"; - const std::string path = "/xyz/openbmc_project/sensors"; - const std::array<std::string, 1> interfaces = { - "xyz.openbmc_project.Sensor.Value"}; - - // Response handler for parsing objects subtree - auto respHandler = - [ callback{std::move(callback)}, SensorsAsyncResp, sensorNames ]( - const boost::system::error_code ec, const GetSubTreeType& subtree) { - BMCWEB_LOG_DEBUG << "getConnections resp_handler enter"; - if (ec) { - SensorsAsyncResp->setErrorStatus(); - BMCWEB_LOG_ERROR << "getConnections resp_handler: Dbus error " << ec; - return; - } + Callback&& callback) +{ + BMCWEB_LOG_DEBUG << "getConnections enter"; + const std::string path = "/xyz/openbmc_project/sensors"; + const std::array<std::string, 1> interfaces = { + "xyz.openbmc_project.Sensor.Value"}; + + // Response handler for parsing objects subtree + auto respHandler = [callback{std::move(callback)}, SensorsAsyncResp, + sensorNames](const boost::system::error_code ec, + const GetSubTreeType& subtree) { + BMCWEB_LOG_DEBUG << "getConnections resp_handler enter"; + if (ec) + { + SensorsAsyncResp->setErrorStatus(); + BMCWEB_LOG_ERROR << "getConnections resp_handler: Dbus error " + << ec; + return; + } - BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " subtrees"; + BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " subtrees"; - // Make unique list of connections only for requested sensor types and - // found in the chassis - boost::container::flat_set<std::string> connections; - // Intrinsic to avoid malloc. Most systems will have < 8 sensor producers - connections.reserve(8); + // Make unique list of connections only for requested sensor types and + // found in the chassis + boost::container::flat_set<std::string> connections; + // Intrinsic to avoid malloc. Most systems will have < 8 sensor + // producers + connections.reserve(8); - BMCWEB_LOG_DEBUG << "sensorNames list count: " << sensorNames.size(); - for (const std::string& tsensor : sensorNames) { - BMCWEB_LOG_DEBUG << "Sensor to find: " << tsensor; - } + BMCWEB_LOG_DEBUG << "sensorNames list count: " << sensorNames.size(); + for (const std::string& tsensor : sensorNames) + { + BMCWEB_LOG_DEBUG << "Sensor to find: " << tsensor; + } - for (const std::pair< - std::string, - std::vector<std::pair<std::string, std::vector<std::string>>>>& - object : subtree) { - for (const char* type : SensorsAsyncResp->types) { - if (boost::starts_with(object.first, type)) { - auto lastPos = object.first.rfind('/'); - if (lastPos != std::string::npos) { - std::string sensorName = object.first.substr(lastPos + 1); - - if (sensorNames.find(sensorName) != sensorNames.end()) { - // For each Connection name - for (const std::pair<std::string, std::vector<std::string>>& - objData : object.second) { - BMCWEB_LOG_DEBUG << "Adding connection: " << objData.first; - connections.insert(objData.first); - } + for (const std::pair< + std::string, + std::vector<std::pair<std::string, std::vector<std::string>>>>& + object : subtree) + { + for (const char* type : SensorsAsyncResp->types) + { + if (boost::starts_with(object.first, type)) + { + auto lastPos = object.first.rfind('/'); + if (lastPos != std::string::npos) + { + std::string sensorName = + object.first.substr(lastPos + 1); + + if (sensorNames.find(sensorName) != sensorNames.end()) + { + // For each Connection name + for (const std::pair<std::string, + std::vector<std::string>>& + objData : object.second) + { + BMCWEB_LOG_DEBUG << "Adding connection: " + << objData.first; + connections.insert(objData.first); + } + } + } + break; + } } - } - break; } - } - } - BMCWEB_LOG_DEBUG << "Found " << connections.size() << " connections"; - callback(std::move(connections)); - BMCWEB_LOG_DEBUG << "getConnections resp_handler exit"; - }; - - // Make call to ObjectMapper to find all sensors objects - crow::connections::systemBus->async_method_call( - std::move(respHandler), "xyz.openbmc_project.ObjectMapper", - "/xyz/openbmc_project/object_mapper", "xyz.openbmc_project.ObjectMapper", - "GetSubTree", path, 2, interfaces); - BMCWEB_LOG_DEBUG << "getConnections exit"; + BMCWEB_LOG_DEBUG << "Found " << connections.size() << " connections"; + callback(std::move(connections)); + BMCWEB_LOG_DEBUG << "getConnections resp_handler exit"; + }; + + // Make call to ObjectMapper to find all sensors objects + crow::connections::systemBus->async_method_call( + std::move(respHandler), "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/object_mapper", + "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, 2, interfaces); + BMCWEB_LOG_DEBUG << "getConnections exit"; } /** @@ -151,64 +173,74 @@ void getConnections(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp, */ template <typename Callback> void getChassis(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp, - Callback&& callback) { - BMCWEB_LOG_DEBUG << "getChassis enter"; - // Process response from EntityManager and extract chassis data - auto respHandler = [ callback{std::move(callback)}, SensorsAsyncResp ]( - const boost::system::error_code ec, ManagedObjectsVectorType& resp) { - BMCWEB_LOG_DEBUG << "getChassis respHandler enter"; - if (ec) { - BMCWEB_LOG_ERROR << "getChassis respHandler DBUS error: " << ec; - SensorsAsyncResp->setErrorStatus(); - return; - } - boost::container::flat_set<std::string> sensorNames; - - // SensorsAsyncResp->chassisId - bool foundChassis = false; - std::vector<std::string> split; - // Reserve space for - // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames - split.reserve(8); - - for (const auto& objDictEntry : resp) { - const std::string& objectPath = - static_cast<const std::string&>(objDictEntry.first); - boost::algorithm::split(split, objectPath, boost::is_any_of("/")); - if (split.size() < 2) { - BMCWEB_LOG_ERROR << "Got path that isn't long enough " << objectPath; - split.clear(); - continue; - } - const std::string& sensorName = split.end()[-1]; - const std::string& chassisName = split.end()[-2]; - - if (chassisName != SensorsAsyncResp->chassisId) { - split.clear(); - continue; - } - BMCWEB_LOG_DEBUG << "New sensor: " << sensorName; - foundChassis = true; - sensorNames.emplace(sensorName); - split.clear(); + Callback&& callback) +{ + BMCWEB_LOG_DEBUG << "getChassis enter"; + // Process response from EntityManager and extract chassis data + auto respHandler = [callback{std::move(callback)}, + SensorsAsyncResp](const boost::system::error_code ec, + ManagedObjectsVectorType& resp) { + BMCWEB_LOG_DEBUG << "getChassis respHandler enter"; + if (ec) + { + BMCWEB_LOG_ERROR << "getChassis respHandler DBUS error: " << ec; + SensorsAsyncResp->setErrorStatus(); + return; + } + boost::container::flat_set<std::string> sensorNames; + + // SensorsAsyncResp->chassisId + bool foundChassis = false; + std::vector<std::string> split; + // Reserve space for + // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames + split.reserve(8); + + for (const auto& objDictEntry : resp) + { + const std::string& objectPath = + static_cast<const std::string&>(objDictEntry.first); + boost::algorithm::split(split, objectPath, boost::is_any_of("/")); + if (split.size() < 2) + { + BMCWEB_LOG_ERROR << "Got path that isn't long enough " + << objectPath; + split.clear(); + continue; + } + const std::string& sensorName = split.end()[-1]; + const std::string& chassisName = split.end()[-2]; + + if (chassisName != SensorsAsyncResp->chassisId) + { + split.clear(); + continue; + } + BMCWEB_LOG_DEBUG << "New sensor: " << sensorName; + foundChassis = true; + sensorNames.emplace(sensorName); + split.clear(); + }; + BMCWEB_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names"; + + if (!foundChassis) + { + BMCWEB_LOG_INFO << "Unable to find chassis named " + << SensorsAsyncResp->chassisId; + SensorsAsyncResp->res.result(boost::beast::http::status::not_found); + } + else + { + callback(sensorNames); + } + BMCWEB_LOG_DEBUG << "getChassis respHandler exit"; }; - BMCWEB_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names"; - - if (!foundChassis) { - BMCWEB_LOG_INFO << "Unable to find chassis named " - << SensorsAsyncResp->chassisId; - SensorsAsyncResp->res.result(boost::beast::http::status::not_found); - } else { - callback(sensorNames); - } - BMCWEB_LOG_DEBUG << "getChassis respHandler exit"; - }; - - // Make call to EntityManager to find all chassis objects - crow::connections::systemBus->async_method_call( - respHandler, "xyz.openbmc_project.EntityManager", "/", - "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); - BMCWEB_LOG_DEBUG << "getChassis exit"; + + // Make call to EntityManager to find all chassis objects + crow::connections::systemBus->async_method_call( + respHandler, "xyz.openbmc_project.EntityManager", "/", + "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); + BMCWEB_LOG_DEBUG << "getChassis exit"; } /** @@ -225,116 +257,146 @@ void objectInterfacesToJson( const boost::container::flat_map< std::string, boost::container::flat_map<std::string, SensorVariant>>& interfacesDict, - nlohmann::json& sensor_json) { - // We need a value interface before we can do anything with it - auto valueIt = interfacesDict.find("xyz.openbmc_project.Sensor.Value"); - if (valueIt == interfacesDict.end()) { - BMCWEB_LOG_ERROR << "Sensor doesn't have a value interface"; - return; - } - - // Assume values exist as is (10^0 == 1) if no scale exists - int64_t scaleMultiplier = 0; - - auto scaleIt = valueIt->second.find("Scale"); - // If a scale exists, pull value as int64, and use the scaling. - if (scaleIt != valueIt->second.end()) { - const int64_t* int64Value = mapbox::getPtr<const int64_t>(scaleIt->second); - if (int64Value != nullptr) { - scaleMultiplier = *int64Value; + nlohmann::json& sensor_json) +{ + // We need a value interface before we can do anything with it + auto valueIt = interfacesDict.find("xyz.openbmc_project.Sensor.Value"); + if (valueIt == interfacesDict.end()) + { + BMCWEB_LOG_ERROR << "Sensor doesn't have a value interface"; + return; } - } - - sensor_json["MemberId"] = sensorName; - sensor_json["Name"] = sensorName; - sensor_json["Status"]["State"] = "Enabled"; - sensor_json["Status"]["Health"] = "OK"; - - // Parameter to set to override the type we get from dbus, and force it to - // int, regardless of what is available. This is used for schemas like fan, - // that require integers, not floats. - bool forceToInt = false; - - const char* unit = "Reading"; - if (sensorType == "temperature") { - unit = "ReadingCelsius"; - sensor_json["@odata.type"] = "#Thermal.v1_3_0.Temperature"; - // TODO(ed) Documentation says that path should be type fan_tach, - // implementation seems to implement fan - } else if (sensorType == "fan" || sensorType == "fan_tach") { - unit = "Reading"; - sensor_json["ReadingUnits"] = "RPM"; - sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan"; - forceToInt = true; - } else if (sensorType == "voltage") { - unit = "ReadingVolts"; - sensor_json["@odata.type"] = "#Power.v1_0_0.Voltage"; - } else { - BMCWEB_LOG_ERROR << "Redfish cannot map object type for " << sensorName; - return; - } - // Map of dbus interface name, dbus property name and redfish property_name - std::vector<std::tuple<const char*, const char*, const char*>> properties; - properties.reserve(7); - - properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit); - properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning", - "WarningHigh", "UpperThresholdNonCritical"); - properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning", - "WarningLow", "LowerThresholdNonCritical"); - properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical", - "CriticalHigh", "UpperThresholdCritical"); - properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical", - "CriticalLow", "LowerThresholdCritical"); - - if (sensorType == "temperature") { - properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue", - "MinReadingRangeTemp"); - properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue", - "MaxReadingRangeTemp"); - } else { - properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue", - "MinReadingRange"); - properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue", - "MaxReadingRange"); - } - - for (const std::tuple<const char*, const char*, const char*>& p : - properties) { - auto interfaceProperties = interfacesDict.find(std::get<0>(p)); - if (interfaceProperties != interfacesDict.end()) { - auto valueIt = interfaceProperties->second.find(std::get<1>(p)); - if (valueIt != interfaceProperties->second.end()) { - const SensorVariant& valueVariant = valueIt->second; - nlohmann::json& valueIt = sensor_json[std::get<2>(p)]; - - // Attempt to pull the int64 directly - const int64_t* int64Value = mapbox::getPtr<const int64_t>(valueVariant); - - if (int64Value != nullptr) { - if (forceToInt || scaleMultiplier >= 0) { - valueIt = *int64Value * std::pow(10, scaleMultiplier); - } else { - valueIt = *int64Value * - std::pow(10, static_cast<double>(scaleMultiplier)); - } + + // Assume values exist as is (10^0 == 1) if no scale exists + int64_t scaleMultiplier = 0; + + auto scaleIt = valueIt->second.find("Scale"); + // If a scale exists, pull value as int64, and use the scaling. + if (scaleIt != valueIt->second.end()) + { + const int64_t* int64Value = + mapbox::getPtr<const int64_t>(scaleIt->second); + if (int64Value != nullptr) + { + scaleMultiplier = *int64Value; } - // Attempt to pull the float directly - const double* doubleValue = mapbox::getPtr<const double>(valueVariant); - - if (doubleValue != nullptr) { - if (!forceToInt) { - valueIt = *doubleValue * - std::pow(10, static_cast<double>(scaleMultiplier)); - } else { - valueIt = static_cast<int64_t>(*doubleValue * - std::pow(10, scaleMultiplier)); - } + } + + sensor_json["MemberId"] = sensorName; + sensor_json["Name"] = sensorName; + sensor_json["Status"]["State"] = "Enabled"; + sensor_json["Status"]["Health"] = "OK"; + + // Parameter to set to override the type we get from dbus, and force it to + // int, regardless of what is available. This is used for schemas like fan, + // that require integers, not floats. + bool forceToInt = false; + + const char* unit = "Reading"; + if (sensorType == "temperature") + { + unit = "ReadingCelsius"; + sensor_json["@odata.type"] = "#Thermal.v1_3_0.Temperature"; + // TODO(ed) Documentation says that path should be type fan_tach, + // implementation seems to implement fan + } + else if (sensorType == "fan" || sensorType == "fan_tach") + { + unit = "Reading"; + sensor_json["ReadingUnits"] = "RPM"; + sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan"; + forceToInt = true; + } + else if (sensorType == "voltage") + { + unit = "ReadingVolts"; + sensor_json["@odata.type"] = "#Power.v1_0_0.Voltage"; + } + else + { + BMCWEB_LOG_ERROR << "Redfish cannot map object type for " << sensorName; + return; + } + // Map of dbus interface name, dbus property name and redfish property_name + std::vector<std::tuple<const char*, const char*, const char*>> properties; + properties.reserve(7); + + properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit); + properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning", + "WarningHigh", "UpperThresholdNonCritical"); + properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning", + "WarningLow", "LowerThresholdNonCritical"); + properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical", + "CriticalHigh", "UpperThresholdCritical"); + properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical", + "CriticalLow", "LowerThresholdCritical"); + + if (sensorType == "temperature") + { + properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue", + "MinReadingRangeTemp"); + properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue", + "MaxReadingRangeTemp"); + } + else + { + properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue", + "MinReadingRange"); + properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue", + "MaxReadingRange"); + } + + for (const std::tuple<const char*, const char*, const char*>& p : + properties) + { + auto interfaceProperties = interfacesDict.find(std::get<0>(p)); + if (interfaceProperties != interfacesDict.end()) + { + auto valueIt = interfaceProperties->second.find(std::get<1>(p)); + if (valueIt != interfaceProperties->second.end()) + { + const SensorVariant& valueVariant = valueIt->second; + nlohmann::json& valueIt = sensor_json[std::get<2>(p)]; + + // Attempt to pull the int64 directly + const int64_t* int64Value = + mapbox::getPtr<const int64_t>(valueVariant); + + if (int64Value != nullptr) + { + if (forceToInt || scaleMultiplier >= 0) + { + valueIt = *int64Value * std::pow(10, scaleMultiplier); + } + else + { + valueIt = + *int64Value * + std::pow(10, static_cast<double>(scaleMultiplier)); + } + } + // Attempt to pull the float directly + const double* doubleValue = + mapbox::getPtr<const double>(valueVariant); + + if (doubleValue != nullptr) + { + if (!forceToInt) + { + valueIt = + *doubleValue * + std::pow(10, static_cast<double>(scaleMultiplier)); + } + else + { + valueIt = static_cast<int64_t>( + *doubleValue * std::pow(10, scaleMultiplier)); + } + } + } } - } } - } - BMCWEB_LOG_DEBUG << "Added sensor " << sensorName; + BMCWEB_LOG_DEBUG << "Added sensor " << sensorName; } /** @@ -342,106 +404,140 @@ void objectInterfacesToJson( * chassis. * @param SensorsAsyncResp Pointer to object holding response data */ -void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp) { - BMCWEB_LOG_DEBUG << "getChassisData enter"; - auto getChassisCb = [&, SensorsAsyncResp]( - boost::container::flat_set<std::string>& - sensorNames) { - BMCWEB_LOG_DEBUG << "getChassisCb enter"; - auto getConnectionCb = - [&, SensorsAsyncResp, sensorNames]( - const boost::container::flat_set<std::string>& connections) { - BMCWEB_LOG_DEBUG << "getConnectionCb enter"; - // Get managed objects from all services exposing sensors - for (const std::string& connection : connections) { - // Response handler to process managed objects - auto getManagedObjectsCb = [&, SensorsAsyncResp, sensorNames]( - const boost::system::error_code ec, - ManagedObjectsVectorType& resp) { - BMCWEB_LOG_DEBUG << "getManagedObjectsCb enter"; - if (ec) { - BMCWEB_LOG_ERROR << "getManagedObjectsCb DBUS error: " << ec; - SensorsAsyncResp->setErrorStatus(); - return; - } - // Go through all objects and update response with - // sensor data - for (const auto& objDictEntry : resp) { - const std::string& objPath = - static_cast<const std::string&>(objDictEntry.first); - BMCWEB_LOG_DEBUG << "getManagedObjectsCb parsing object " - << objPath; - - std::vector<std::string> split; - // Reserve space for - // /xyz/openbmc_project/sensors/<name>/<subname> - split.reserve(6); - boost::algorithm::split(split, objPath, boost::is_any_of("/")); - if (split.size() < 6) { - BMCWEB_LOG_ERROR << "Got path that isn't long enough " - << objPath; - continue; - } - // These indexes aren't intuitive, as boost::split puts an empty - // string at the beggining - const std::string& sensorType = split[4]; - const std::string& sensorName = split[5]; - BMCWEB_LOG_DEBUG << "sensorName " << sensorName - << " sensorType " << sensorType; - if (sensorNames.find(sensorName) == sensorNames.end()) { - BMCWEB_LOG_ERROR << sensorName << " not in sensor list "; - continue; - } - - const char* fieldName = nullptr; - if (sensorType == "temperature") { - fieldName = "Temperatures"; - } else if (sensorType == "fan" || sensorType == "fan_tach") { - fieldName = "Fans"; - } else if (sensorType == "voltage") { - fieldName = "Voltages"; - } else if (sensorType == "current") { - fieldName = "PowerSupply"; - } else if (sensorType == "power") { - fieldName = "PowerSupply"; - } else { - BMCWEB_LOG_ERROR << "Unsure how to handle sensorType " - << sensorType; - continue; - } - - nlohmann::json& tempArray = - SensorsAsyncResp->res.jsonValue[fieldName]; - - // Create the array if it doesn't yet exist - if (tempArray.is_array() == false) { - tempArray = nlohmann::json::array(); - } - - tempArray.push_back( - {{"@odata.id", "/redfish/v1/Chassis/" + - SensorsAsyncResp->chassisId + - "/Thermal#/" + sensorName}}); - nlohmann::json& sensorJson = tempArray.back(); - objectInterfacesToJson(sensorName, sensorType, - objDictEntry.second, sensorJson); - } - BMCWEB_LOG_DEBUG << "getManagedObjectsCb exit"; +void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp) +{ + BMCWEB_LOG_DEBUG << "getChassisData enter"; + auto getChassisCb = [&, SensorsAsyncResp]( + boost::container::flat_set<std::string>& + sensorNames) { + BMCWEB_LOG_DEBUG << "getChassisCb enter"; + auto getConnectionCb = + [&, SensorsAsyncResp, sensorNames]( + const boost::container::flat_set<std::string>& connections) { + BMCWEB_LOG_DEBUG << "getConnectionCb enter"; + // Get managed objects from all services exposing sensors + for (const std::string& connection : connections) + { + // Response handler to process managed objects + auto getManagedObjectsCb = + [&, SensorsAsyncResp, + sensorNames](const boost::system::error_code ec, + ManagedObjectsVectorType& resp) { + BMCWEB_LOG_DEBUG << "getManagedObjectsCb enter"; + if (ec) + { + BMCWEB_LOG_ERROR + << "getManagedObjectsCb DBUS error: " << ec; + SensorsAsyncResp->setErrorStatus(); + return; + } + // Go through all objects and update response with + // sensor data + for (const auto& objDictEntry : resp) + { + const std::string& objPath = + static_cast<const std::string&>( + objDictEntry.first); + BMCWEB_LOG_DEBUG + << "getManagedObjectsCb parsing object " + << objPath; + + std::vector<std::string> split; + // Reserve space for + // /xyz/openbmc_project/sensors/<name>/<subname> + split.reserve(6); + boost::algorithm::split(split, objPath, + boost::is_any_of("/")); + if (split.size() < 6) + { + BMCWEB_LOG_ERROR + << "Got path that isn't long enough " + << objPath; + continue; + } + // These indexes aren't intuitive, as + // boost::split puts an empty string at the + // beggining + const std::string& sensorType = split[4]; + const std::string& sensorName = split[5]; + BMCWEB_LOG_DEBUG << "sensorName " << sensorName + << " sensorType " + << sensorType; + if (sensorNames.find(sensorName) == + sensorNames.end()) + { + BMCWEB_LOG_ERROR << sensorName + << " not in sensor list "; + continue; + } + + const char* fieldName = nullptr; + if (sensorType == "temperature") + { + fieldName = "Temperatures"; + } + else if (sensorType == "fan" || + sensorType == "fan_tach") + { + fieldName = "Fans"; + } + else if (sensorType == "voltage") + { + fieldName = "Voltages"; + } + else if (sensorType == "current") + { + fieldName = "PowerSupply"; + } + else if (sensorType == "power") + { + fieldName = "PowerSupply"; + } + else + { + BMCWEB_LOG_ERROR + << "Unsure how to handle sensorType " + << sensorType; + continue; + } + + nlohmann::json& tempArray = + SensorsAsyncResp->res.jsonValue[fieldName]; + + // Create the array if it doesn't yet exist + if (tempArray.is_array() == false) + { + tempArray = nlohmann::json::array(); + } + + tempArray.push_back( + {{"@odata.id", + "/redfish/v1/Chassis/" + + SensorsAsyncResp->chassisId + + "/Thermal#/" + sensorName}}); + nlohmann::json& sensorJson = tempArray.back(); + objectInterfacesToJson(sensorName, sensorType, + objDictEntry.second, + sensorJson); + } + BMCWEB_LOG_DEBUG << "getManagedObjectsCb exit"; + }; + crow::connections::systemBus->async_method_call( + getManagedObjectsCb, connection, "/", + "org.freedesktop.DBus.ObjectManager", + "GetManagedObjects"); + }; + BMCWEB_LOG_DEBUG << "getConnectionCb exit"; }; - crow::connections::systemBus->async_method_call( - getManagedObjectsCb, connection, "/", - "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); - }; - BMCWEB_LOG_DEBUG << "getConnectionCb exit"; - }; - // get connections and then pass it to get sensors - getConnections(SensorsAsyncResp, sensorNames, std::move(getConnectionCb)); - BMCWEB_LOG_DEBUG << "getChassisCb exit"; - }; - - // get chassis information related to sensors - getChassis(SensorsAsyncResp, std::move(getChassisCb)); - BMCWEB_LOG_DEBUG << "getChassisData exit"; + // get connections and then pass it to get sensors + getConnections(SensorsAsyncResp, sensorNames, + std::move(getConnectionCb)); + BMCWEB_LOG_DEBUG << "getChassisCb exit"; + }; + + // get chassis information related to sensors + getChassis(SensorsAsyncResp, std::move(getChassisCb)); + BMCWEB_LOG_DEBUG << "getChassisData exit"; }; -} // namespace redfish +} // namespace redfish |