diff options
author | Gunnar Mills <gmills@us.ibm.com> | 2020-10-14 22:55:29 +0300 |
---|---|---|
committer | Gunnar Mills <gmills@us.ibm.com> | 2020-10-16 16:09:57 +0300 |
commit | ac6a4445047df7f9fa198cca2ae1eeffd943a627 (patch) | |
tree | 5e947f5cf3b4dfeaeafa4fae89442abf6d5c225e /redfish-core/lib | |
parent | 116bcc5c254d6dc8af09ba30f36c90c47b269a82 (diff) | |
download | bmcweb-ac6a4445047df7f9fa198cca2ae1eeffd943a627.tar.xz |
cpudimm.hpp: Separate Memory and Processor functionality
To match other files move Redfish Memory classes and functions
to a separate memory.hpp file. This naming "memory" (after the Redfish
schemas) matches other filenames. Do the same with Processor
classes and functions, moving to a separate processor.hpp.
cpudimm.hpp had grown to 1300+ lines. Makes development and review
easier.
Tested: Validator passes. Resources look the same.
Change-Id: I7e23ecaf9b4b69cc72aad6d94ad3a555ee76b28a
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
Diffstat (limited to 'redfish-core/lib')
-rw-r--r-- | redfish-core/lib/memory.hpp (renamed from redfish-core/lib/cpudimm.hpp) | 499 | ||||
-rw-r--r-- | redfish-core/lib/processor.hpp | 527 |
2 files changed, 527 insertions, 499 deletions
diff --git a/redfish-core/lib/cpudimm.hpp b/redfish-core/lib/memory.hpp index 9351f6ab6d..a172233b5a 100644 --- a/redfish-core/lib/cpudimm.hpp +++ b/redfish-core/lib/memory.hpp @@ -26,418 +26,6 @@ namespace redfish { -using InterfacesProperties = boost::container::flat_map< - std::string, - boost::container::flat_map<std::string, dbus::utility::DbusVariantType>>; - -inline void - getCpuDataByInterface(const std::shared_ptr<AsyncResp>& aResp, - const InterfacesProperties& cpuInterfacesProperties) -{ - BMCWEB_LOG_DEBUG << "Get CPU resources by interface."; - - // Added for future purpose. Once present and functional attributes added - // in busctl call, need to add actual logic to fetch original values. - bool present = false; - const bool functional = true; - auto health = std::make_shared<HealthPopulate>(aResp); - health->populate(); - - for (const auto& interface : cpuInterfacesProperties) - { - for (const auto& property : interface.second) - { - if (property.first == "CoreCount") - { - const uint16_t* coresCount = - std::get_if<uint16_t>(&property.second); - if (coresCount == nullptr) - { - // Important property not in desired type - messages::internalError(aResp->res); - return; - } - if (*coresCount == 0) - { - // Slot is not populated, set status end return - aResp->res.jsonValue["Status"]["State"] = "Absent"; - // HTTP Code will be set up automatically, just return - return; - } - aResp->res.jsonValue["Status"]["State"] = "Enabled"; - present = true; - aResp->res.jsonValue["TotalCores"] = *coresCount; - } - else if (property.first == "Socket") - { - const std::string* value = - std::get_if<std::string>(&property.second); - if (value != nullptr) - { - aResp->res.jsonValue["Socket"] = *value; - } - } - else if (property.first == "ThreadCount") - { - const int64_t* value = std::get_if<int64_t>(&property.second); - if (value != nullptr) - { - aResp->res.jsonValue["TotalThreads"] = *value; - } - } - else if (property.first == "Family") - { - const std::string* value = - std::get_if<std::string>(&property.second); - if (value != nullptr) - { - aResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] = - *value; - } - } - else if (property.first == "Id") - { - const uint64_t* value = std::get_if<uint64_t>(&property.second); - if (value != nullptr && *value != 0) - { - present = true; - aResp->res - .jsonValue["ProcessorId"]["IdentificationRegisters"] = - boost::lexical_cast<std::string>(*value); - } - } - } - } - - if (present == false) - { - aResp->res.jsonValue["Status"]["State"] = "Absent"; - aResp->res.jsonValue["Status"]["Health"] = "OK"; - } - else - { - aResp->res.jsonValue["Status"]["State"] = "Enabled"; - if (functional) - { - aResp->res.jsonValue["Status"]["Health"] = "OK"; - } - else - { - aResp->res.jsonValue["Status"]["Health"] = "Critical"; - } - } - - return; -} - -inline void getCpuDataByService(std::shared_ptr<AsyncResp> aResp, - const std::string& cpuId, - const std::string& service, - const std::string& objPath) -{ - BMCWEB_LOG_DEBUG << "Get available system cpu resources by service."; - - crow::connections::systemBus->async_method_call( - [cpuId, service, objPath, aResp{std::move(aResp)}]( - const boost::system::error_code ec, - const dbus::utility::ManagedObjectType& dbusData) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error"; - messages::internalError(aResp->res); - return; - } - aResp->res.jsonValue["Id"] = cpuId; - aResp->res.jsonValue["Name"] = "Processor"; - aResp->res.jsonValue["ProcessorType"] = "CPU"; - - bool slotPresent = false; - std::string corePath = objPath + "/core"; - size_t totalCores = 0; - for (const auto& object : dbusData) - { - if (object.first.str == objPath) - { - getCpuDataByInterface(aResp, object.second); - } - else if (boost::starts_with(object.first.str, corePath)) - { - for (const auto& interface : object.second) - { - if (interface.first == - "xyz.openbmc_project.Inventory.Item") - { - for (const auto& property : interface.second) - { - if (property.first == "Present") - { - const bool* present = - std::get_if<bool>(&property.second); - if (present != nullptr) - { - if (*present == true) - { - slotPresent = true; - totalCores++; - } - } - } - } - } - } - } - } - // In getCpuDataByInterface(), state and health are set - // based on the present and functional status. If core - // count is zero, then it has a higher precedence. - if (slotPresent) - { - if (totalCores == 0) - { - // Slot is not populated, set status end return - aResp->res.jsonValue["Status"]["State"] = "Absent"; - aResp->res.jsonValue["Status"]["Health"] = "OK"; - } - aResp->res.jsonValue["TotalCores"] = totalCores; - } - return; - }, - service, "/xyz/openbmc_project/inventory", - "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); -} - -inline void getCpuAssetData(std::shared_ptr<AsyncResp> aResp, - const std::string& service, - const std::string& objPath) -{ - BMCWEB_LOG_DEBUG << "Get Cpu Asset Data"; - crow::connections::systemBus->async_method_call( - [objPath, aResp{std::move(aResp)}]( - const boost::system::error_code ec, - const boost::container::flat_map< - std::string, std::variant<std::string, uint32_t, uint16_t, - bool>>& properties) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error"; - messages::internalError(aResp->res); - return; - } - - for (const auto& property : properties) - { - if (property.first == "SerialNumber") - { - const std::string* sn = - std::get_if<std::string>(&property.second); - if (sn != nullptr && !sn->empty()) - { - aResp->res.jsonValue["SerialNumber"] = *sn; - } - } - else if (property.first == "Model") - { - const std::string* model = - std::get_if<std::string>(&property.second); - if (model != nullptr && !model->empty()) - { - aResp->res.jsonValue["Model"] = *model; - } - } - else if (property.first == "Manufacturer") - { - - const std::string* mfg = - std::get_if<std::string>(&property.second); - if (mfg != nullptr) - { - aResp->res.jsonValue["Manufacturer"] = *mfg; - - // Otherwise would be unexpected. - if (mfg->find("Intel") != std::string::npos) - { - aResp->res.jsonValue["ProcessorArchitecture"] = - "x86"; - aResp->res.jsonValue["InstructionSet"] = "x86-64"; - } - else if (mfg->find("IBM") != std::string::npos) - { - aResp->res.jsonValue["ProcessorArchitecture"] = - "Power"; - aResp->res.jsonValue["InstructionSet"] = "PowerISA"; - } - } - } - } - }, - service, objPath, "org.freedesktop.DBus.Properties", "GetAll", - "xyz.openbmc_project.Inventory.Decorator.Asset"); -} - -inline void getCpuRevisionData(std::shared_ptr<AsyncResp> aResp, - const std::string& service, - const std::string& objPath) -{ - BMCWEB_LOG_DEBUG << "Get Cpu Revision Data"; - crow::connections::systemBus->async_method_call( - [objPath, aResp{std::move(aResp)}]( - const boost::system::error_code ec, - const boost::container::flat_map< - std::string, std::variant<std::string, uint32_t, uint16_t, - bool>>& properties) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error"; - messages::internalError(aResp->res); - return; - } - - for (const auto& property : properties) - { - if (property.first == "Version") - { - const std::string* ver = - std::get_if<std::string>(&property.second); - if (ver != nullptr) - { - aResp->res.jsonValue["Version"] = *ver; - } - break; - } - } - }, - service, objPath, "org.freedesktop.DBus.Properties", "GetAll", - "xyz.openbmc_project.Inventory.Decorator.Revision"); -} - -inline void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp, - const std::string& acclrtrId, - const std::string& service, - const std::string& objPath) -{ - BMCWEB_LOG_DEBUG - << "Get available system Accelerator resources by service."; - crow::connections::systemBus->async_method_call( - [acclrtrId, aResp{std::move(aResp)}]( - const boost::system::error_code ec, - const boost::container::flat_map< - std::string, std::variant<std::string, uint32_t, uint16_t, - bool>>& properties) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error"; - messages::internalError(aResp->res); - return; - } - aResp->res.jsonValue["Id"] = acclrtrId; - aResp->res.jsonValue["Name"] = "Processor"; - const bool* accPresent = nullptr; - const bool* accFunctional = nullptr; - - for (const auto& property : properties) - { - if (property.first == "Functional") - { - accFunctional = std::get_if<bool>(&property.second); - } - else if (property.first == "Present") - { - accPresent = std::get_if<bool>(&property.second); - } - } - - std::string state = "Enabled"; - std::string health = "OK"; - - if (accPresent != nullptr && *accPresent == false) - { - state = "Absent"; - } - - if ((accFunctional != nullptr) && (*accFunctional == false)) - { - if (state == "Enabled") - { - health = "Critical"; - } - } - - aResp->res.jsonValue["Status"]["State"] = state; - aResp->res.jsonValue["Status"]["Health"] = health; - aResp->res.jsonValue["ProcessorType"] = "Accelerator"; - }, - service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); -} - -inline void getProcessorData(std::shared_ptr<AsyncResp> aResp, - const std::string& processorId, - const std::vector<const char*>& inventoryItems) -{ - BMCWEB_LOG_DEBUG << "Get available system processor resources."; - - crow::connections::systemBus->async_method_call( - [processorId, aResp{std::move(aResp)}]( - const boost::system::error_code ec, - const boost::container::flat_map< - std::string, boost::container::flat_map< - std::string, std::vector<std::string>>>& - subtree) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error"; - messages::internalError(aResp->res); - return; - } - for (const auto& object : subtree) - { - if (boost::ends_with(object.first, processorId)) - { - for (const auto& service : object.second) - { - for (const auto& inventory : service.second) - { - if (inventory == "xyz.openbmc_project." - "Inventory.Decorator.Asset") - { - getCpuAssetData(aResp, service.first, - object.first); - } - else if (inventory == - "xyz.openbmc_project." - "Inventory.Decorator.Revision") - { - getCpuRevisionData(aResp, service.first, - object.first); - } - else if (inventory == "xyz.openbmc_project." - "Inventory.Item.Cpu") - { - getCpuDataByService(aResp, processorId, - service.first, - object.first); - } - else if (inventory == "xyz.openbmc_project." - "Inventory.Item.Accelerator") - { - getAcceleratorDataByService(aResp, processorId, - service.first, - object.first); - } - } - } - return; - } - } - // Object not found - messages::resourceNotFound(aResp->res, "Processor", processorId); - return; - }, - "xyz.openbmc_project.ObjectMapper", - "/xyz/openbmc_project/object_mapper", - "xyz.openbmc_project.ObjectMapper", "GetSubTree", - "/xyz/openbmc_project/inventory", 0, inventoryItems); -} - using DimmProperty = std::variant<std::string, std::vector<uint32_t>, std::vector<uint16_t>, uint64_t, uint32_t, uint16_t, uint8_t, bool>; @@ -1148,93 +736,6 @@ inline void getDimmData(std::shared_ptr<AsyncResp> aResp, "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); } -class ProcessorCollection : public Node -{ - public: - /* - * Default Constructor - */ - ProcessorCollection(App& app) : - Node(app, "/redfish/v1/Systems/system/Processors/") - { - entityPrivileges = { - {boost::beast::http::verb::get, {{"Login"}}}, - {boost::beast::http::verb::head, {{"Login"}}}, - {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; - } - - private: - /** - * Functions triggers appropriate requests on DBus - */ - void doGet(crow::Response& res, const crow::Request&, - const std::vector<std::string>&) override - { - res.jsonValue["@odata.type"] = - "#ProcessorCollection.ProcessorCollection"; - res.jsonValue["Name"] = "Processor Collection"; - - res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/"; - auto asyncResp = std::make_shared<AsyncResp>(res); - - collection_util::getResourceList( - asyncResp, "Processors", - {"xyz.openbmc_project.Inventory.Item.Cpu", - "xyz.openbmc_project.Inventory.Item.Accelerator"}); - } -}; - -class Processor : public Node -{ - public: - /* - * Default Constructor - */ - Processor(App& app) : - Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string()) - { - entityPrivileges = { - {boost::beast::http::verb::get, {{"Login"}}}, - {boost::beast::http::verb::head, {{"Login"}}}, - {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; - } - - private: - /** - * Functions triggers appropriate requests on DBus - */ - void doGet(crow::Response& res, const crow::Request&, - const std::vector<std::string>& params) override - { - // Check if there is required param, truly entering this shall be - // impossible - if (params.size() != 1) - { - messages::internalError(res); - - res.end(); - return; - } - const std::string& processorId = params[0]; - res.jsonValue["@odata.type"] = "#Processor.v1_9_0.Processor"; - res.jsonValue["@odata.id"] = - "/redfish/v1/Systems/system/Processors/" + processorId; - - auto asyncResp = std::make_shared<AsyncResp>(res); - - getProcessorData(asyncResp, processorId, - {"xyz.openbmc_project.Inventory.Item.Cpu", - "xyz.openbmc_project.Inventory.Decorator.Asset", - "xyz.openbmc_project.Inventory.Item.Accelerator"}); - } -}; - class MemoryCollection : public Node { public: diff --git a/redfish-core/lib/processor.hpp b/redfish-core/lib/processor.hpp new file mode 100644 index 0000000000..5c986845f4 --- /dev/null +++ b/redfish-core/lib/processor.hpp @@ -0,0 +1,527 @@ +/* +// Copyright (c) 2018 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ +#pragma once + +#include "health.hpp" + +#include <boost/container/flat_map.hpp> +#include <node.hpp> +#include <utils/collection.hpp> +#include <utils/json_utils.hpp> + +namespace redfish +{ + +using InterfacesProperties = boost::container::flat_map< + std::string, + boost::container::flat_map<std::string, dbus::utility::DbusVariantType>>; + +inline void + getCpuDataByInterface(const std::shared_ptr<AsyncResp>& aResp, + const InterfacesProperties& cpuInterfacesProperties) +{ + BMCWEB_LOG_DEBUG << "Get CPU resources by interface."; + + // Added for future purpose. Once present and functional attributes added + // in busctl call, need to add actual logic to fetch original values. + bool present = false; + const bool functional = true; + auto health = std::make_shared<HealthPopulate>(aResp); + health->populate(); + + for (const auto& interface : cpuInterfacesProperties) + { + for (const auto& property : interface.second) + { + if (property.first == "CoreCount") + { + const uint16_t* coresCount = + std::get_if<uint16_t>(&property.second); + if (coresCount == nullptr) + { + // Important property not in desired type + messages::internalError(aResp->res); + return; + } + if (*coresCount == 0) + { + // Slot is not populated, set status end return + aResp->res.jsonValue["Status"]["State"] = "Absent"; + // HTTP Code will be set up automatically, just return + return; + } + aResp->res.jsonValue["Status"]["State"] = "Enabled"; + present = true; + aResp->res.jsonValue["TotalCores"] = *coresCount; + } + else if (property.first == "Socket") + { + const std::string* value = + std::get_if<std::string>(&property.second); + if (value != nullptr) + { + aResp->res.jsonValue["Socket"] = *value; + } + } + else if (property.first == "ThreadCount") + { + const int64_t* value = std::get_if<int64_t>(&property.second); + if (value != nullptr) + { + aResp->res.jsonValue["TotalThreads"] = *value; + } + } + else if (property.first == "Family") + { + const std::string* value = + std::get_if<std::string>(&property.second); + if (value != nullptr) + { + aResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] = + *value; + } + } + else if (property.first == "Id") + { + const uint64_t* value = std::get_if<uint64_t>(&property.second); + if (value != nullptr && *value != 0) + { + present = true; + aResp->res + .jsonValue["ProcessorId"]["IdentificationRegisters"] = + boost::lexical_cast<std::string>(*value); + } + } + } + } + + if (present == false) + { + aResp->res.jsonValue["Status"]["State"] = "Absent"; + aResp->res.jsonValue["Status"]["Health"] = "OK"; + } + else + { + aResp->res.jsonValue["Status"]["State"] = "Enabled"; + if (functional) + { + aResp->res.jsonValue["Status"]["Health"] = "OK"; + } + else + { + aResp->res.jsonValue["Status"]["Health"] = "Critical"; + } + } + + return; +} + +inline void getCpuDataByService(std::shared_ptr<AsyncResp> aResp, + const std::string& cpuId, + const std::string& service, + const std::string& objPath) +{ + BMCWEB_LOG_DEBUG << "Get available system cpu resources by service."; + + crow::connections::systemBus->async_method_call( + [cpuId, service, objPath, aResp{std::move(aResp)}]( + const boost::system::error_code ec, + const dbus::utility::ManagedObjectType& dbusData) { + if (ec) + { + BMCWEB_LOG_DEBUG << "DBUS response error"; + messages::internalError(aResp->res); + return; + } + aResp->res.jsonValue["Id"] = cpuId; + aResp->res.jsonValue["Name"] = "Processor"; + aResp->res.jsonValue["ProcessorType"] = "CPU"; + + bool slotPresent = false; + std::string corePath = objPath + "/core"; + size_t totalCores = 0; + for (const auto& object : dbusData) + { + if (object.first.str == objPath) + { + getCpuDataByInterface(aResp, object.second); + } + else if (boost::starts_with(object.first.str, corePath)) + { + for (const auto& interface : object.second) + { + if (interface.first == + "xyz.openbmc_project.Inventory.Item") + { + for (const auto& property : interface.second) + { + if (property.first == "Present") + { + const bool* present = + std::get_if<bool>(&property.second); + if (present != nullptr) + { + if (*present == true) + { + slotPresent = true; + totalCores++; + } + } + } + } + } + } + } + } + // In getCpuDataByInterface(), state and health are set + // based on the present and functional status. If core + // count is zero, then it has a higher precedence. + if (slotPresent) + { + if (totalCores == 0) + { + // Slot is not populated, set status end return + aResp->res.jsonValue["Status"]["State"] = "Absent"; + aResp->res.jsonValue["Status"]["Health"] = "OK"; + } + aResp->res.jsonValue["TotalCores"] = totalCores; + } + return; + }, + service, "/xyz/openbmc_project/inventory", + "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); +} + +inline void getCpuAssetData(std::shared_ptr<AsyncResp> aResp, + const std::string& service, + const std::string& objPath) +{ + BMCWEB_LOG_DEBUG << "Get Cpu Asset Data"; + crow::connections::systemBus->async_method_call( + [objPath, aResp{std::move(aResp)}]( + const boost::system::error_code ec, + const boost::container::flat_map< + std::string, std::variant<std::string, uint32_t, uint16_t, + bool>>& properties) { + if (ec) + { + BMCWEB_LOG_DEBUG << "DBUS response error"; + messages::internalError(aResp->res); + return; + } + + for (const auto& property : properties) + { + if (property.first == "SerialNumber") + { + const std::string* sn = + std::get_if<std::string>(&property.second); + if (sn != nullptr && !sn->empty()) + { + aResp->res.jsonValue["SerialNumber"] = *sn; + } + } + else if (property.first == "Model") + { + const std::string* model = + std::get_if<std::string>(&property.second); + if (model != nullptr && !model->empty()) + { + aResp->res.jsonValue["Model"] = *model; + } + } + else if (property.first == "Manufacturer") + { + + const std::string* mfg = + std::get_if<std::string>(&property.second); + if (mfg != nullptr) + { + aResp->res.jsonValue["Manufacturer"] = *mfg; + + // Otherwise would be unexpected. + if (mfg->find("Intel") != std::string::npos) + { + aResp->res.jsonValue["ProcessorArchitecture"] = + "x86"; + aResp->res.jsonValue["InstructionSet"] = "x86-64"; + } + else if (mfg->find("IBM") != std::string::npos) + { + aResp->res.jsonValue["ProcessorArchitecture"] = + "Power"; + aResp->res.jsonValue["InstructionSet"] = "PowerISA"; + } + } + } + } + }, + service, objPath, "org.freedesktop.DBus.Properties", "GetAll", + "xyz.openbmc_project.Inventory.Decorator.Asset"); +} + +inline void getCpuRevisionData(std::shared_ptr<AsyncResp> aResp, + const std::string& service, + const std::string& objPath) +{ + BMCWEB_LOG_DEBUG << "Get Cpu Revision Data"; + crow::connections::systemBus->async_method_call( + [objPath, aResp{std::move(aResp)}]( + const boost::system::error_code ec, + const boost::container::flat_map< + std::string, std::variant<std::string, uint32_t, uint16_t, + bool>>& properties) { + if (ec) + { + BMCWEB_LOG_DEBUG << "DBUS response error"; + messages::internalError(aResp->res); + return; + } + + for (const auto& property : properties) + { + if (property.first == "Version") + { + const std::string* ver = + std::get_if<std::string>(&property.second); + if (ver != nullptr) + { + aResp->res.jsonValue["Version"] = *ver; + } + break; + } + } + }, + service, objPath, "org.freedesktop.DBus.Properties", "GetAll", + "xyz.openbmc_project.Inventory.Decorator.Revision"); +} + +inline void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp, + const std::string& acclrtrId, + const std::string& service, + const std::string& objPath) +{ + BMCWEB_LOG_DEBUG + << "Get available system Accelerator resources by service."; + crow::connections::systemBus->async_method_call( + [acclrtrId, aResp{std::move(aResp)}]( + const boost::system::error_code ec, + const boost::container::flat_map< + std::string, std::variant<std::string, uint32_t, uint16_t, + bool>>& properties) { + if (ec) + { + BMCWEB_LOG_DEBUG << "DBUS response error"; + messages::internalError(aResp->res); + return; + } + aResp->res.jsonValue["Id"] = acclrtrId; + aResp->res.jsonValue["Name"] = "Processor"; + const bool* accPresent = nullptr; + const bool* accFunctional = nullptr; + + for (const auto& property : properties) + { + if (property.first == "Functional") + { + accFunctional = std::get_if<bool>(&property.second); + } + else if (property.first == "Present") + { + accPresent = std::get_if<bool>(&property.second); + } + } + + std::string state = "Enabled"; + std::string health = "OK"; + + if (accPresent != nullptr && *accPresent == false) + { + state = "Absent"; + } + + if ((accFunctional != nullptr) && (*accFunctional == false)) + { + if (state == "Enabled") + { + health = "Critical"; + } + } + + aResp->res.jsonValue["Status"]["State"] = state; + aResp->res.jsonValue["Status"]["Health"] = health; + aResp->res.jsonValue["ProcessorType"] = "Accelerator"; + }, + service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); +} + +inline void getProcessorData(std::shared_ptr<AsyncResp> aResp, + const std::string& processorId, + const std::vector<const char*>& inventoryItems) +{ + BMCWEB_LOG_DEBUG << "Get available system processor resources."; + + crow::connections::systemBus->async_method_call( + [processorId, aResp{std::move(aResp)}]( + const boost::system::error_code ec, + const boost::container::flat_map< + std::string, boost::container::flat_map< + std::string, std::vector<std::string>>>& + subtree) { + if (ec) + { + BMCWEB_LOG_DEBUG << "DBUS response error"; + messages::internalError(aResp->res); + return; + } + for (const auto& object : subtree) + { + if (boost::ends_with(object.first, processorId)) + { + for (const auto& service : object.second) + { + for (const auto& inventory : service.second) + { + if (inventory == "xyz.openbmc_project." + "Inventory.Decorator.Asset") + { + getCpuAssetData(aResp, service.first, + object.first); + } + else if (inventory == + "xyz.openbmc_project." + "Inventory.Decorator.Revision") + { + getCpuRevisionData(aResp, service.first, + object.first); + } + else if (inventory == "xyz.openbmc_project." + "Inventory.Item.Cpu") + { + getCpuDataByService(aResp, processorId, + service.first, + object.first); + } + else if (inventory == "xyz.openbmc_project." + "Inventory.Item.Accelerator") + { + getAcceleratorDataByService(aResp, processorId, + service.first, + object.first); + } + } + } + return; + } + } + // Object not found + messages::resourceNotFound(aResp->res, "Processor", processorId); + return; + }, + "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/object_mapper", + "xyz.openbmc_project.ObjectMapper", "GetSubTree", + "/xyz/openbmc_project/inventory", 0, inventoryItems); +} + +class ProcessorCollection : public Node +{ + public: + /* + * Default Constructor + */ + ProcessorCollection(App& app) : + Node(app, "/redfish/v1/Systems/system/Processors/") + { + entityPrivileges = { + {boost::beast::http::verb::get, {{"Login"}}}, + {boost::beast::http::verb::head, {{"Login"}}}, + {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; + } + + private: + /** + * Functions triggers appropriate requests on DBus + */ + void doGet(crow::Response& res, const crow::Request&, + const std::vector<std::string>&) override + { + res.jsonValue["@odata.type"] = + "#ProcessorCollection.ProcessorCollection"; + res.jsonValue["Name"] = "Processor Collection"; + + res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/"; + auto asyncResp = std::make_shared<AsyncResp>(res); + + collection_util::getResourceList( + asyncResp, "Processors", + {"xyz.openbmc_project.Inventory.Item.Cpu", + "xyz.openbmc_project.Inventory.Item.Accelerator"}); + } +}; + +class Processor : public Node +{ + public: + /* + * Default Constructor + */ + Processor(App& app) : + Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string()) + { + entityPrivileges = { + {boost::beast::http::verb::get, {{"Login"}}}, + {boost::beast::http::verb::head, {{"Login"}}}, + {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; + } + + private: + /** + * Functions triggers appropriate requests on DBus + */ + void doGet(crow::Response& res, const crow::Request&, + const std::vector<std::string>& params) override + { + // Check if there is required param, truly entering this shall be + // impossible + if (params.size() != 1) + { + messages::internalError(res); + + res.end(); + return; + } + const std::string& processorId = params[0]; + res.jsonValue["@odata.type"] = "#Processor.v1_9_0.Processor"; + res.jsonValue["@odata.id"] = + "/redfish/v1/Systems/system/Processors/" + processorId; + + auto asyncResp = std::make_shared<AsyncResp>(res); + + getProcessorData(asyncResp, processorId, + {"xyz.openbmc_project.Inventory.Item.Cpu", + "xyz.openbmc_project.Inventory.Decorator.Asset", + "xyz.openbmc_project.Inventory.Item.Accelerator"}); + } +}; + +} // namespace redfish |