1c5b2abe0SLewanczyk, Dawid /* 2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation 3c5b2abe0SLewanczyk, Dawid // 4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License"); 5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License. 6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at 7c5b2abe0SLewanczyk, Dawid // 8c5b2abe0SLewanczyk, Dawid // http://www.apache.org/licenses/LICENSE-2.0 9c5b2abe0SLewanczyk, Dawid // 10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software 11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS, 12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and 14c5b2abe0SLewanczyk, Dawid // limitations under the License. 15c5b2abe0SLewanczyk, Dawid */ 16c5b2abe0SLewanczyk, Dawid #pragma once 17c5b2abe0SLewanczyk, Dawid 18c5b2abe0SLewanczyk, Dawid #include <error_messages.hpp> 19c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp> 20c5b2abe0SLewanczyk, Dawid #include "node.hpp" 21c5b2abe0SLewanczyk, Dawid #include "boost/container/flat_map.hpp" 22c5b2abe0SLewanczyk, Dawid 23c5b2abe0SLewanczyk, Dawid namespace redfish { 24c5b2abe0SLewanczyk, Dawid 25c5b2abe0SLewanczyk, Dawid /** 26c5b2abe0SLewanczyk, Dawid * SystemAsyncResp 27c5b2abe0SLewanczyk, Dawid * Gathers data needed for response processing after async calls are done 28c5b2abe0SLewanczyk, Dawid */ 29c5b2abe0SLewanczyk, Dawid class SystemAsyncResp { 30c5b2abe0SLewanczyk, Dawid public: 3155c7b7a2SEd Tanous SystemAsyncResp(crow::Response &response) : res(response) {} 32c5b2abe0SLewanczyk, Dawid 33c5b2abe0SLewanczyk, Dawid ~SystemAsyncResp() { 34c5b2abe0SLewanczyk, Dawid if (res.result() != (boost::beast::http::status::ok)) { 35c5b2abe0SLewanczyk, Dawid // Reset the json object to clear out any data that made it in before the 36c5b2abe0SLewanczyk, Dawid // error happened 37c5b2abe0SLewanczyk, Dawid // todo(ed) handle error condition with proper code 3855c7b7a2SEd Tanous res.jsonValue = messages::internalError(); 39c5b2abe0SLewanczyk, Dawid } 40c5b2abe0SLewanczyk, Dawid res.end(); 41c5b2abe0SLewanczyk, Dawid } 42c5b2abe0SLewanczyk, Dawid 43c5b2abe0SLewanczyk, Dawid void setErrorStatus() { 44c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 45c5b2abe0SLewanczyk, Dawid } 46c5b2abe0SLewanczyk, Dawid 4755c7b7a2SEd Tanous crow::Response &res; 48c5b2abe0SLewanczyk, Dawid }; 49c5b2abe0SLewanczyk, Dawid 50c5b2abe0SLewanczyk, Dawid /** 51c5b2abe0SLewanczyk, Dawid * OnDemandSystemsProvider 52c5b2abe0SLewanczyk, Dawid * Board provider class that retrieves data directly from dbus, before seting 53c5b2abe0SLewanczyk, Dawid * it into JSON output. This does not cache any data. 54c5b2abe0SLewanczyk, Dawid * 55c5b2abe0SLewanczyk, Dawid * Class can be a good example on how to scale different data providing 56c5b2abe0SLewanczyk, Dawid * solutions to produce single schema output. 57c5b2abe0SLewanczyk, Dawid * 58c5b2abe0SLewanczyk, Dawid * TODO(Pawel) 59c5b2abe0SLewanczyk, Dawid * This perhaps shall be different file, which has to be chosen on compile time 60c5b2abe0SLewanczyk, Dawid * depending on OEM needs 61c5b2abe0SLewanczyk, Dawid */ 62c5b2abe0SLewanczyk, Dawid class OnDemandSystemsProvider { 63c5b2abe0SLewanczyk, Dawid public: 64c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 65c5b2abe0SLewanczyk, Dawid void getBaseboardList(CallbackFunc &&callback) { 6655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get list of available boards."; 6755c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 68c5b2abe0SLewanczyk, Dawid [callback{std::move(callback)}](const boost::system::error_code ec, 69c5b2abe0SLewanczyk, Dawid const std::vector<std::string> &resp) { 70c5b2abe0SLewanczyk, Dawid // Callback requires vector<string> to retrieve all available board 71c5b2abe0SLewanczyk, Dawid // list. 72*d76323e5SEd Tanous std::vector<std::string> boardList; 73c5b2abe0SLewanczyk, Dawid if (ec) { 74c5b2abe0SLewanczyk, Dawid // Something wrong on DBus, the error_code is not important at this 75c5b2abe0SLewanczyk, Dawid // moment, just return success=false, and empty output. Since size 76c5b2abe0SLewanczyk, Dawid // of vector may vary depending on information from Entity Manager, 77c5b2abe0SLewanczyk, Dawid // and empty output could not be treated same way as error. 78*d76323e5SEd Tanous callback(false, boardList); 79c5b2abe0SLewanczyk, Dawid return; 80c5b2abe0SLewanczyk, Dawid } 8155c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards."; 82c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 83c5b2abe0SLewanczyk, Dawid for (const std::string &objpath : resp) { 84*d76323e5SEd Tanous std::size_t lastPos = objpath.rfind("/"); 85*d76323e5SEd Tanous if (lastPos != std::string::npos) { 86*d76323e5SEd Tanous boardList.emplace_back(objpath.substr(lastPos + 1)); 87c5b2abe0SLewanczyk, Dawid } 88c5b2abe0SLewanczyk, Dawid } 89c5b2abe0SLewanczyk, Dawid // Finally make a callback with useful data 90*d76323e5SEd Tanous callback(true, boardList); 91c5b2abe0SLewanczyk, Dawid }, 92c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 93c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 94c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", 95c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/inventory", int32_t(0), 96c5b2abe0SLewanczyk, Dawid std::array<const char *, 1>{ 97c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.Board"}); 98c5b2abe0SLewanczyk, Dawid }; 99c5b2abe0SLewanczyk, Dawid 100c5b2abe0SLewanczyk, Dawid /** 101c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 102c5b2abe0SLewanczyk, Dawid * 103c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls 104c5b2abe0SLewanczyk, Dawid * @param[in] name Computer system name from request 105c5b2abe0SLewanczyk, Dawid * 106c5b2abe0SLewanczyk, Dawid * @return None. 107c5b2abe0SLewanczyk, Dawid */ 108c5b2abe0SLewanczyk, Dawid void getComputerSystem(std::shared_ptr<SystemAsyncResp> aResp, 109c5b2abe0SLewanczyk, Dawid const std::string &name) { 110c5b2abe0SLewanczyk, Dawid const std::array<const char *, 5> interfaces = { 111c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Decorator.Asset", 112c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.Cpu", 113c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.Dimm", 114c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.System", 115c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Common.UUID", 116c5b2abe0SLewanczyk, Dawid }; 11755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 11855c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 119c5b2abe0SLewanczyk, Dawid [ name, aResp{std::move(aResp)} ]( 120c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 121c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 122c5b2abe0SLewanczyk, Dawid std::string, 123c5b2abe0SLewanczyk, Dawid std::vector<std::pair<std::string, std::vector<std::string>>>>> 124c5b2abe0SLewanczyk, Dawid &subtree) { 125c5b2abe0SLewanczyk, Dawid if (ec) { 12655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 127c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 128c5b2abe0SLewanczyk, Dawid return; 129c5b2abe0SLewanczyk, Dawid } 130c5b2abe0SLewanczyk, Dawid bool foundName = false; 131c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 132c5b2abe0SLewanczyk, Dawid for (const std::pair<std::string, 133c5b2abe0SLewanczyk, Dawid std::vector<std::pair<std::string, 134c5b2abe0SLewanczyk, Dawid std::vector<std::string>>>> 135c5b2abe0SLewanczyk, Dawid &object : subtree) { 136c5b2abe0SLewanczyk, Dawid const std::string &path = object.first; 13755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 138c5b2abe0SLewanczyk, Dawid const std::vector<std::pair<std::string, std::vector<std::string>>> 139c5b2abe0SLewanczyk, Dawid &connectionNames = object.second; 140c5b2abe0SLewanczyk, Dawid if (connectionNames.size() < 1) { 141c5b2abe0SLewanczyk, Dawid continue; 142c5b2abe0SLewanczyk, Dawid } 143c5b2abe0SLewanczyk, Dawid // Check if computer system exist 144c5b2abe0SLewanczyk, Dawid if (boost::ends_with(path, name)) { 145c5b2abe0SLewanczyk, Dawid foundName = true; 14655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Found name: " << name; 147c5b2abe0SLewanczyk, Dawid const std::string connectionName = connectionNames[0].first; 14855c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 149c5b2abe0SLewanczyk, Dawid [ aResp, name(std::string(name)) ]( 150c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 151c5b2abe0SLewanczyk, Dawid const std::vector<std::pair<std::string, VariantType>> 152c5b2abe0SLewanczyk, Dawid &propertiesList) { 153c5b2abe0SLewanczyk, Dawid if (ec) { 15455c7b7a2SEd Tanous BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 155c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 156c5b2abe0SLewanczyk, Dawid return; 157c5b2abe0SLewanczyk, Dawid } 15855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << propertiesList.size() 159c5b2abe0SLewanczyk, Dawid << "properties for system"; 160c5b2abe0SLewanczyk, Dawid for (const std::pair<std::string, VariantType> &property : 161c5b2abe0SLewanczyk, Dawid propertiesList) { 162c5b2abe0SLewanczyk, Dawid const std::string *value = 16355c7b7a2SEd Tanous mapbox::getPtr<const std::string>(property.second); 164c5b2abe0SLewanczyk, Dawid if (value != nullptr) { 16555c7b7a2SEd Tanous aResp->res.jsonValue[property.first] = *value; 166c5b2abe0SLewanczyk, Dawid } 167c5b2abe0SLewanczyk, Dawid } 16855c7b7a2SEd Tanous aResp->res.jsonValue["Name"] = name; 16955c7b7a2SEd Tanous aResp->res.jsonValue["Id"] = 17055c7b7a2SEd Tanous aResp->res.jsonValue["SerialNumber"]; 171c5b2abe0SLewanczyk, Dawid }, 172c5b2abe0SLewanczyk, Dawid connectionName, path, "org.freedesktop.DBus.Properties", 173c5b2abe0SLewanczyk, Dawid "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset"); 174c5b2abe0SLewanczyk, Dawid } else { 175c5b2abe0SLewanczyk, Dawid // This is not system, so check if it's cpu, dimm, UUID or BiosVer 176c5b2abe0SLewanczyk, Dawid for (auto const &s : connectionNames) { 177c5b2abe0SLewanczyk, Dawid for (auto const &i : s.second) { 178c5b2abe0SLewanczyk, Dawid if (boost::ends_with(i, "Dimm")) { 17955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Found Dimm, now get it properties."; 18055c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 181c5b2abe0SLewanczyk, Dawid [&, aResp](const boost::system::error_code ec, 182c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 183c5b2abe0SLewanczyk, Dawid std::string, VariantType>> &properties) { 184c5b2abe0SLewanczyk, Dawid if (ec) { 18555c7b7a2SEd Tanous BMCWEB_LOG_ERROR << "DBUS response error " << ec; 186c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 187c5b2abe0SLewanczyk, Dawid return; 188c5b2abe0SLewanczyk, Dawid } 18955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 190c5b2abe0SLewanczyk, Dawid << "Dimm properties."; 191c5b2abe0SLewanczyk, Dawid for (const auto &p : properties) { 192c5b2abe0SLewanczyk, Dawid if (p.first == "MemorySize") { 193c5b2abe0SLewanczyk, Dawid const std::string *value = 19455c7b7a2SEd Tanous mapbox::getPtr<const std::string>(p.second); 195c5b2abe0SLewanczyk, Dawid if ((value != nullptr) && (*value != "NULL")) { 196c5b2abe0SLewanczyk, Dawid // Remove units char 197c5b2abe0SLewanczyk, Dawid int32_t unitCoeff; 198c5b2abe0SLewanczyk, Dawid if (boost::ends_with(*value, "MB")) { 199c5b2abe0SLewanczyk, Dawid unitCoeff = 1000; 200c5b2abe0SLewanczyk, Dawid } else if (boost::ends_with(*value, "KB")) { 201c5b2abe0SLewanczyk, Dawid unitCoeff = 1000000; 202c5b2abe0SLewanczyk, Dawid } else { 203a434f2bdSEd Tanous BMCWEB_LOG_ERROR 204a434f2bdSEd Tanous << "Unsupported memory units"; 205c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 206c5b2abe0SLewanczyk, Dawid return; 207c5b2abe0SLewanczyk, Dawid } 208c5b2abe0SLewanczyk, Dawid 209c5b2abe0SLewanczyk, Dawid auto memSize = boost::lexical_cast<int>( 210c5b2abe0SLewanczyk, Dawid value->substr(0, value->length() - 2)); 21155c7b7a2SEd Tanous aResp->res.jsonValue["TotalSystemMemoryGiB"] += 212c5b2abe0SLewanczyk, Dawid memSize * unitCoeff; 21355c7b7a2SEd Tanous aResp->res.jsonValue["MemorySummary"]["Status"] 214c5b2abe0SLewanczyk, Dawid ["State"] = "Enabled"; 215c5b2abe0SLewanczyk, Dawid } 216c5b2abe0SLewanczyk, Dawid } 217c5b2abe0SLewanczyk, Dawid } 218c5b2abe0SLewanczyk, Dawid }, 219c5b2abe0SLewanczyk, Dawid s.first, path, "org.freedesktop.DBus.Properties", 220c5b2abe0SLewanczyk, Dawid "GetAll", "xyz.openbmc_project.Inventory.Item.Dimm"); 221c5b2abe0SLewanczyk, Dawid } else if (boost::ends_with(i, "Cpu")) { 22255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Found Cpu, now get it properties."; 22355c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 224c5b2abe0SLewanczyk, Dawid [&, aResp](const boost::system::error_code ec, 225c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 226c5b2abe0SLewanczyk, Dawid std::string, VariantType>> &properties) { 227c5b2abe0SLewanczyk, Dawid if (ec) { 22855c7b7a2SEd Tanous BMCWEB_LOG_ERROR << "DBUS response error " << ec; 229c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 230c5b2abe0SLewanczyk, Dawid return; 231c5b2abe0SLewanczyk, Dawid } 23255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 233c5b2abe0SLewanczyk, Dawid << "Cpu properties."; 234c5b2abe0SLewanczyk, Dawid for (const auto &p : properties) { 235c5b2abe0SLewanczyk, Dawid if (p.first == "ProcessorFamily") { 236c5b2abe0SLewanczyk, Dawid const std::string *value = 23755c7b7a2SEd Tanous mapbox::getPtr<const std::string>(p.second); 238c5b2abe0SLewanczyk, Dawid if (value != nullptr) { 239c5b2abe0SLewanczyk, Dawid aResp->res 24055c7b7a2SEd Tanous .jsonValue["ProcessorSummary"]["Count"] = 241c5b2abe0SLewanczyk, Dawid aResp->res 24255c7b7a2SEd Tanous .jsonValue["ProcessorSummary"]["Count"] 243c5b2abe0SLewanczyk, Dawid .get<int>() + 244c5b2abe0SLewanczyk, Dawid 1; 24555c7b7a2SEd Tanous aResp->res.jsonValue["ProcessorSummary"] 246c5b2abe0SLewanczyk, Dawid ["Status"]["State"] = 247c5b2abe0SLewanczyk, Dawid "Enabled"; 248c5b2abe0SLewanczyk, Dawid aResp->res 24955c7b7a2SEd Tanous .jsonValue["ProcessorSummary"]["Model"] = 250c5b2abe0SLewanczyk, Dawid *value; 251c5b2abe0SLewanczyk, Dawid } 252c5b2abe0SLewanczyk, Dawid } 253c5b2abe0SLewanczyk, Dawid } 254c5b2abe0SLewanczyk, Dawid }, 255c5b2abe0SLewanczyk, Dawid s.first, path, "org.freedesktop.DBus.Properties", 256c5b2abe0SLewanczyk, Dawid "GetAll", "xyz.openbmc_project.Inventory.Item.Cpu"); 257c5b2abe0SLewanczyk, Dawid } else if (boost::ends_with(i, "UUID")) { 25855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Found UUID, now get it properties."; 25955c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 260c5b2abe0SLewanczyk, Dawid [aResp](const boost::system::error_code ec, 261c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 262c5b2abe0SLewanczyk, Dawid std::string, VariantType>> &properties) { 263c5b2abe0SLewanczyk, Dawid if (ec) { 26455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 265c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 266c5b2abe0SLewanczyk, Dawid return; 267c5b2abe0SLewanczyk, Dawid } 26855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 269c5b2abe0SLewanczyk, Dawid << "UUID properties."; 270c5b2abe0SLewanczyk, Dawid for (const std::pair<std::string, VariantType> &p : 271c5b2abe0SLewanczyk, Dawid properties) { 272c5b2abe0SLewanczyk, Dawid if (p.first == "BIOSVer") { 273c5b2abe0SLewanczyk, Dawid const std::string *value = 27455c7b7a2SEd Tanous mapbox::getPtr<const std::string>(p.second); 275c5b2abe0SLewanczyk, Dawid if (value != nullptr) { 27655c7b7a2SEd Tanous aResp->res.jsonValue["BiosVersion"] = *value; 277c5b2abe0SLewanczyk, Dawid } 278c5b2abe0SLewanczyk, Dawid } 279c5b2abe0SLewanczyk, Dawid if (p.first == "UUID") { 280c5b2abe0SLewanczyk, Dawid const std::string *value = 28155c7b7a2SEd Tanous mapbox::getPtr<const std::string>(p.second); 28255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "UUID = " << *value 283c5b2abe0SLewanczyk, Dawid << " length " << value->length(); 284c5b2abe0SLewanczyk, Dawid if (value != nullptr) { 285c5b2abe0SLewanczyk, Dawid // Workaround for to short return str in smbios 286c5b2abe0SLewanczyk, Dawid // demo app, 32 bytes are described by spec 287c5b2abe0SLewanczyk, Dawid if (value->length() > 0 && 288c5b2abe0SLewanczyk, Dawid value->length() < 32) { 289c5b2abe0SLewanczyk, Dawid std::string correctedValue = *value; 290c5b2abe0SLewanczyk, Dawid correctedValue.append(32 - value->length(), 291c5b2abe0SLewanczyk, Dawid '0'); 292c5b2abe0SLewanczyk, Dawid value = &correctedValue; 293c5b2abe0SLewanczyk, Dawid } else if (value->length() == 32) { 29455c7b7a2SEd Tanous aResp->res.jsonValue["UUID"] = 295c5b2abe0SLewanczyk, Dawid value->substr(0, 8) + "-" + 296c5b2abe0SLewanczyk, Dawid value->substr(8, 4) + "-" + 297c5b2abe0SLewanczyk, Dawid value->substr(12, 4) + "-" + 298c5b2abe0SLewanczyk, Dawid value->substr(16, 4) + "-" + 299c5b2abe0SLewanczyk, Dawid value->substr(20, 12); 300c5b2abe0SLewanczyk, Dawid } 301c5b2abe0SLewanczyk, Dawid } 302c5b2abe0SLewanczyk, Dawid } 303c5b2abe0SLewanczyk, Dawid } 304c5b2abe0SLewanczyk, Dawid }, 305c5b2abe0SLewanczyk, Dawid s.first, path, "org.freedesktop.DBus.Properties", 306c5b2abe0SLewanczyk, Dawid "GetAll", "xyz.openbmc_project.Common.UUID"); 307c5b2abe0SLewanczyk, Dawid } 308c5b2abe0SLewanczyk, Dawid } 309c5b2abe0SLewanczyk, Dawid } 310c5b2abe0SLewanczyk, Dawid } 311c5b2abe0SLewanczyk, Dawid } 312c5b2abe0SLewanczyk, Dawid if (foundName == false) { 313c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 314c5b2abe0SLewanczyk, Dawid } 315c5b2abe0SLewanczyk, Dawid }, 316c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 317c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 318c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTree", 319c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/inventory", int32_t(0), interfaces); 320c5b2abe0SLewanczyk, Dawid } 321c5b2abe0SLewanczyk, Dawid 322c5b2abe0SLewanczyk, Dawid /** 323c5b2abe0SLewanczyk, Dawid * @brief Retrieves identify led group properties over dbus 324c5b2abe0SLewanczyk, Dawid * 325c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 326c5b2abe0SLewanczyk, Dawid * @param[in] callback Callback for process retrieved data. 327c5b2abe0SLewanczyk, Dawid * 328c5b2abe0SLewanczyk, Dawid * @return None. 329c5b2abe0SLewanczyk, Dawid */ 330c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 331c5b2abe0SLewanczyk, Dawid void getLedGroupIdentify(std::shared_ptr<SystemAsyncResp> aResp, 332c5b2abe0SLewanczyk, Dawid CallbackFunc &&callback) { 33355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get led groups"; 33455c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 3358ceb2ecaSEd Tanous [ 3368ceb2ecaSEd Tanous aResp{std::move(aResp)}, &callback 3378ceb2ecaSEd Tanous ](const boost::system::error_code &ec, const ManagedObjectsType &resp) { 338c5b2abe0SLewanczyk, Dawid if (ec) { 33955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 340c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 341c5b2abe0SLewanczyk, Dawid return; 342c5b2abe0SLewanczyk, Dawid } 34355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects."; 344c5b2abe0SLewanczyk, Dawid for (const auto &objPath : resp) { 345c5b2abe0SLewanczyk, Dawid const std::string &path = objPath.first; 346c5b2abe0SLewanczyk, Dawid if (path.rfind("enclosure_identify") != std::string::npos) { 347c5b2abe0SLewanczyk, Dawid for (const auto &interface : objPath.second) { 348c5b2abe0SLewanczyk, Dawid if (interface.first == "xyz.openbmc_project.Led.Group") { 349c5b2abe0SLewanczyk, Dawid for (const auto &property : interface.second) { 350c5b2abe0SLewanczyk, Dawid if (property.first == "Asserted") { 351c5b2abe0SLewanczyk, Dawid const bool *asserted = 35255c7b7a2SEd Tanous mapbox::getPtr<const bool>(property.second); 353c5b2abe0SLewanczyk, Dawid if (nullptr != asserted) { 354c5b2abe0SLewanczyk, Dawid callback(*asserted, aResp); 355c5b2abe0SLewanczyk, Dawid } else { 356c5b2abe0SLewanczyk, Dawid callback(false, aResp); 357c5b2abe0SLewanczyk, Dawid } 358c5b2abe0SLewanczyk, Dawid } 359c5b2abe0SLewanczyk, Dawid } 360c5b2abe0SLewanczyk, Dawid } 361c5b2abe0SLewanczyk, Dawid } 362c5b2abe0SLewanczyk, Dawid } 363c5b2abe0SLewanczyk, Dawid } 364c5b2abe0SLewanczyk, Dawid }, 365c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.GroupManager", 366c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager", 367c5b2abe0SLewanczyk, Dawid "GetManagedObjects"); 368c5b2abe0SLewanczyk, Dawid } 369c5b2abe0SLewanczyk, Dawid 370c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 371c5b2abe0SLewanczyk, Dawid void getLedIdentify(std::shared_ptr<SystemAsyncResp> aResp, 372c5b2abe0SLewanczyk, Dawid CallbackFunc &&callback) { 37355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get identify led properties"; 37455c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 3758ceb2ecaSEd Tanous [ aResp{std::move(aResp)}, &callback ]( 3768ceb2ecaSEd Tanous const boost::system::error_code ec, 377c5b2abe0SLewanczyk, Dawid const PropertiesType &properties) { 378c5b2abe0SLewanczyk, Dawid if (ec) { 37955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 380c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 381c5b2abe0SLewanczyk, Dawid return; 382c5b2abe0SLewanczyk, Dawid } 38355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() << "led properties."; 384c5b2abe0SLewanczyk, Dawid std::string output; 385c5b2abe0SLewanczyk, Dawid for (const auto &property : properties) { 386c5b2abe0SLewanczyk, Dawid if (property.first == "State") { 387c5b2abe0SLewanczyk, Dawid const std::string *s = 38855c7b7a2SEd Tanous mapbox::getPtr<std::string>(property.second); 389c5b2abe0SLewanczyk, Dawid if (nullptr != s) { 39055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Identify Led State: " << *s; 391c5b2abe0SLewanczyk, Dawid const auto pos = s->rfind('.'); 392c5b2abe0SLewanczyk, Dawid if (pos != std::string::npos) { 393c5b2abe0SLewanczyk, Dawid auto led = s->substr(pos + 1); 394c5b2abe0SLewanczyk, Dawid for (const std::pair<const char *, const char *> &p : 395c5b2abe0SLewanczyk, Dawid std::array<std::pair<const char *, const char *>, 3>{ 396c5b2abe0SLewanczyk, Dawid {{"On", "Lit"}, 397c5b2abe0SLewanczyk, Dawid {"Blink", "Blinking"}, 398c5b2abe0SLewanczyk, Dawid {"Off", "Off"}}}) { 399c5b2abe0SLewanczyk, Dawid if (led == p.first) { 400c5b2abe0SLewanczyk, Dawid output = p.second; 401c5b2abe0SLewanczyk, Dawid } 402c5b2abe0SLewanczyk, Dawid } 403c5b2abe0SLewanczyk, Dawid } 404c5b2abe0SLewanczyk, Dawid } 405c5b2abe0SLewanczyk, Dawid } 406c5b2abe0SLewanczyk, Dawid } 407c5b2abe0SLewanczyk, Dawid callback(output, aResp); 408c5b2abe0SLewanczyk, Dawid }, 409c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 410c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 411c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "GetAll", 412c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical"); 413c5b2abe0SLewanczyk, Dawid } 414c5b2abe0SLewanczyk, Dawid 415c5b2abe0SLewanczyk, Dawid /** 416c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 417c5b2abe0SLewanczyk, Dawid * 418c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 419c5b2abe0SLewanczyk, Dawid * 420c5b2abe0SLewanczyk, Dawid * @return None. 421c5b2abe0SLewanczyk, Dawid */ 422c5b2abe0SLewanczyk, Dawid void getHostState(std::shared_ptr<SystemAsyncResp> aResp) { 42355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 42455c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 425c5b2abe0SLewanczyk, Dawid [aResp{std::move(aResp)}](const boost::system::error_code ec, 426c5b2abe0SLewanczyk, Dawid const PropertiesType &properties) { 427c5b2abe0SLewanczyk, Dawid if (ec) { 42855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 429c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 430c5b2abe0SLewanczyk, Dawid return; 431c5b2abe0SLewanczyk, Dawid } 43255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() << "host properties."; 433c5b2abe0SLewanczyk, Dawid for (const auto &property : properties) { 434c5b2abe0SLewanczyk, Dawid if (property.first == "CurrentHostState") { 435c5b2abe0SLewanczyk, Dawid const std::string *s = 43655c7b7a2SEd Tanous mapbox::getPtr<const std::string>(property.second); 43755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Host state: " << *s; 438c5b2abe0SLewanczyk, Dawid if (nullptr != s) { 439c5b2abe0SLewanczyk, Dawid const auto pos = s->rfind('.'); 440c5b2abe0SLewanczyk, Dawid if (pos != std::string::npos) { 441c5b2abe0SLewanczyk, Dawid // Verify Host State 442c5b2abe0SLewanczyk, Dawid if (s->substr(pos + 1) == "Running") { 44355c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 44455c7b7a2SEd Tanous aResp->res.jsonValue["Status"]["State"] = "Enabled"; 445c5b2abe0SLewanczyk, Dawid } else { 44655c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 44755c7b7a2SEd Tanous aResp->res.jsonValue["Status"]["State"] = "Disabled"; 448c5b2abe0SLewanczyk, Dawid } 449c5b2abe0SLewanczyk, Dawid } 450c5b2abe0SLewanczyk, Dawid } 451c5b2abe0SLewanczyk, Dawid } 452c5b2abe0SLewanczyk, Dawid } 453c5b2abe0SLewanczyk, Dawid }, 454c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 455c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "GetAll", 456c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.State.Host"); 457c5b2abe0SLewanczyk, Dawid } 458c5b2abe0SLewanczyk, Dawid }; 459c5b2abe0SLewanczyk, Dawid 460c5b2abe0SLewanczyk, Dawid /** 461c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 462c5b2abe0SLewanczyk, Dawid * Schema 463c5b2abe0SLewanczyk, Dawid */ 464c5b2abe0SLewanczyk, Dawid class SystemsCollection : public Node { 465c5b2abe0SLewanczyk, Dawid public: 466c5b2abe0SLewanczyk, Dawid SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/") { 467c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = 468c5b2abe0SLewanczyk, Dawid "#ComputerSystemCollection.ComputerSystemCollection"; 469c5b2abe0SLewanczyk, Dawid Node::json["@odata.id"] = "/redfish/v1/Systems"; 470c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 471c5b2abe0SLewanczyk, Dawid "/redfish/v1/" 472c5b2abe0SLewanczyk, Dawid "$metadata#ComputerSystemCollection.ComputerSystemCollection"; 473c5b2abe0SLewanczyk, Dawid Node::json["Name"] = "Computer System Collection"; 474c5b2abe0SLewanczyk, Dawid 475c5b2abe0SLewanczyk, Dawid entityPrivileges = { 476c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 477c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 478c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 479c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 480c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 481c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 482c5b2abe0SLewanczyk, Dawid } 483c5b2abe0SLewanczyk, Dawid 484c5b2abe0SLewanczyk, Dawid private: 485c5b2abe0SLewanczyk, Dawid /** 486c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 487c5b2abe0SLewanczyk, Dawid */ 48855c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 489c5b2abe0SLewanczyk, Dawid const std::vector<std::string> ¶ms) override { 490c5b2abe0SLewanczyk, Dawid // Get board list, and call the below callback for JSON preparation 491c5b2abe0SLewanczyk, Dawid provider.getBaseboardList( 492c5b2abe0SLewanczyk, Dawid [&](const bool &success, const std::vector<std::string> &output) { 493c5b2abe0SLewanczyk, Dawid if (success) { 494c5b2abe0SLewanczyk, Dawid // ... prepare json array with appropriate @odata.id links 495c5b2abe0SLewanczyk, Dawid nlohmann::json boardArray = nlohmann::json::array(); 496*d76323e5SEd Tanous for (const std::string &boardItem : output) { 497c5b2abe0SLewanczyk, Dawid boardArray.push_back( 498*d76323e5SEd Tanous {{"@odata.id", "/redfish/v1/Systems/" + boardItem}}); 499c5b2abe0SLewanczyk, Dawid } 500c5b2abe0SLewanczyk, Dawid // Then attach members, count size and return, 501c5b2abe0SLewanczyk, Dawid Node::json["Members"] = boardArray; 502c5b2abe0SLewanczyk, Dawid Node::json["Members@odata.count"] = boardArray.size(); 50355c7b7a2SEd Tanous res.jsonValue = Node::json; 504c5b2abe0SLewanczyk, Dawid } else { 505c5b2abe0SLewanczyk, Dawid // ... otherwise, return INTERNALL ERROR 506c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 507c5b2abe0SLewanczyk, Dawid } 508c5b2abe0SLewanczyk, Dawid res.end(); 509c5b2abe0SLewanczyk, Dawid }); 510c5b2abe0SLewanczyk, Dawid } 511c5b2abe0SLewanczyk, Dawid 512c5b2abe0SLewanczyk, Dawid OnDemandSystemsProvider provider; 513c5b2abe0SLewanczyk, Dawid }; 514c5b2abe0SLewanczyk, Dawid 515c5b2abe0SLewanczyk, Dawid /** 516c5b2abe0SLewanczyk, Dawid * Systems override class for delivering ComputerSystems Schema 517c5b2abe0SLewanczyk, Dawid */ 518c5b2abe0SLewanczyk, Dawid class Systems : public Node { 519c5b2abe0SLewanczyk, Dawid public: 520c5b2abe0SLewanczyk, Dawid /* 521c5b2abe0SLewanczyk, Dawid * Default Constructor 522c5b2abe0SLewanczyk, Dawid */ 523c5b2abe0SLewanczyk, Dawid Systems(CrowApp &app) 524c5b2abe0SLewanczyk, Dawid : Node(app, "/redfish/v1/Systems/<str>/", std::string()) { 525c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem"; 526c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 527c5b2abe0SLewanczyk, Dawid "/redfish/v1/$metadata#ComputerSystem.ComputerSystem"; 528c5b2abe0SLewanczyk, Dawid Node::json["SystemType"] = "Physical"; 529c5b2abe0SLewanczyk, Dawid Node::json["Description"] = "Computer System"; 530c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideEnabled"] = 531c5b2abe0SLewanczyk, Dawid "Disabled"; // TODO(Dawid), get real boot data 532c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideTarget"] = 533c5b2abe0SLewanczyk, Dawid "None"; // TODO(Dawid), get real boot data 534c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideMode"] = 535c5b2abe0SLewanczyk, Dawid "Legacy"; // TODO(Dawid), get real boot data 536c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 537c5b2abe0SLewanczyk, Dawid "None", "Pxe", "Hdd", "Cd", 538c5b2abe0SLewanczyk, Dawid "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot data 539c5b2abe0SLewanczyk, Dawid Node::json["ProcessorSummary"]["Count"] = int(0); 540c5b2abe0SLewanczyk, Dawid Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled"; 541c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0); 542c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["Status"]["State"] = "Disabled"; 543c5b2abe0SLewanczyk, Dawid 544c5b2abe0SLewanczyk, Dawid entityPrivileges = { 545c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 546c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 547c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 548c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 549c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 550c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 551c5b2abe0SLewanczyk, Dawid } 552c5b2abe0SLewanczyk, Dawid 553c5b2abe0SLewanczyk, Dawid private: 554c5b2abe0SLewanczyk, Dawid OnDemandSystemsProvider provider; 555c5b2abe0SLewanczyk, Dawid 556c5b2abe0SLewanczyk, Dawid /** 557c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 558c5b2abe0SLewanczyk, Dawid */ 55955c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 560c5b2abe0SLewanczyk, Dawid const std::vector<std::string> ¶ms) override { 561c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 562c5b2abe0SLewanczyk, Dawid // impossible 563c5b2abe0SLewanczyk, Dawid if (params.size() != 1) { 564c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 565c5b2abe0SLewanczyk, Dawid res.end(); 566c5b2abe0SLewanczyk, Dawid return; 567c5b2abe0SLewanczyk, Dawid } 568c5b2abe0SLewanczyk, Dawid 569c5b2abe0SLewanczyk, Dawid const std::string &name = params[0]; 570c5b2abe0SLewanczyk, Dawid 57155c7b7a2SEd Tanous res.jsonValue = Node::json; 57255c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 573c5b2abe0SLewanczyk, Dawid 574c5b2abe0SLewanczyk, Dawid auto asyncResp = std::make_shared<SystemAsyncResp>(res); 575c5b2abe0SLewanczyk, Dawid 576c5b2abe0SLewanczyk, Dawid provider.getLedGroupIdentify( 577c5b2abe0SLewanczyk, Dawid asyncResp, [&](const bool &asserted, 578c5b2abe0SLewanczyk, Dawid const std::shared_ptr<SystemAsyncResp> &aResp) { 579c5b2abe0SLewanczyk, Dawid if (asserted) { 580c5b2abe0SLewanczyk, Dawid // If led group is asserted, then another call is needed to 581c5b2abe0SLewanczyk, Dawid // get led status 582c5b2abe0SLewanczyk, Dawid provider.getLedIdentify( 583c5b2abe0SLewanczyk, Dawid aResp, [](const std::string &ledStatus, 584c5b2abe0SLewanczyk, Dawid const std::shared_ptr<SystemAsyncResp> &aResp) { 585c5b2abe0SLewanczyk, Dawid if (!ledStatus.empty()) { 58655c7b7a2SEd Tanous aResp->res.jsonValue["IndicatorLED"] = ledStatus; 587c5b2abe0SLewanczyk, Dawid } 588c5b2abe0SLewanczyk, Dawid }); 589c5b2abe0SLewanczyk, Dawid } else { 59055c7b7a2SEd Tanous aResp->res.jsonValue["IndicatorLED"] = "Off"; 591c5b2abe0SLewanczyk, Dawid } 592c5b2abe0SLewanczyk, Dawid }); 593c5b2abe0SLewanczyk, Dawid provider.getComputerSystem(asyncResp, name); 594c5b2abe0SLewanczyk, Dawid provider.getHostState(asyncResp); 595c5b2abe0SLewanczyk, Dawid } 596c5b2abe0SLewanczyk, Dawid 59755c7b7a2SEd Tanous void doPatch(crow::Response &res, const crow::Request &req, 598c5b2abe0SLewanczyk, Dawid const std::vector<std::string> ¶ms) override { 599c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 600c5b2abe0SLewanczyk, Dawid // impossible 601c5b2abe0SLewanczyk, Dawid if (params.size() != 1) { 602c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 603c5b2abe0SLewanczyk, Dawid res.end(); 604c5b2abe0SLewanczyk, Dawid return; 605c5b2abe0SLewanczyk, Dawid } 606c5b2abe0SLewanczyk, Dawid // Parse JSON request body 607c5b2abe0SLewanczyk, Dawid nlohmann::json patch; 608c5b2abe0SLewanczyk, Dawid if (!json_util::processJsonFromRequest(res, req, patch)) { 609c5b2abe0SLewanczyk, Dawid return; 610c5b2abe0SLewanczyk, Dawid } 611c5b2abe0SLewanczyk, Dawid // Find key with new led value 612c5b2abe0SLewanczyk, Dawid const std::string &name = params[0]; 613c5b2abe0SLewanczyk, Dawid const std::string *reqLedState = nullptr; 614c5b2abe0SLewanczyk, Dawid json_util::Result r = json_util::getString( 615c5b2abe0SLewanczyk, Dawid "IndicatorLED", patch, reqLedState, 616c5b2abe0SLewanczyk, Dawid static_cast<int>(json_util::MessageSetting::TYPE_ERROR) | 617c5b2abe0SLewanczyk, Dawid static_cast<int>(json_util::MessageSetting::MISSING), 61855c7b7a2SEd Tanous res.jsonValue, std::string("/" + name + "/IndicatorLED")); 619c5b2abe0SLewanczyk, Dawid if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr)) { 620c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::bad_request); 621c5b2abe0SLewanczyk, Dawid res.end(); 622c5b2abe0SLewanczyk, Dawid return; 623c5b2abe0SLewanczyk, Dawid } 624c5b2abe0SLewanczyk, Dawid // Verify key value 625c5b2abe0SLewanczyk, Dawid std::string dbusLedState; 626c5b2abe0SLewanczyk, Dawid for (const auto &p : boost::container::flat_map<const char *, const char *>{ 627c5b2abe0SLewanczyk, Dawid {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}}) { 628c5b2abe0SLewanczyk, Dawid if (*reqLedState == p.second) { 629c5b2abe0SLewanczyk, Dawid dbusLedState = p.first; 630c5b2abe0SLewanczyk, Dawid } 631c5b2abe0SLewanczyk, Dawid } 632c5b2abe0SLewanczyk, Dawid 633c5b2abe0SLewanczyk, Dawid // Update led status 634c5b2abe0SLewanczyk, Dawid auto asyncResp = std::make_shared<SystemAsyncResp>(res); 63555c7b7a2SEd Tanous res.jsonValue = Node::json; 63655c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 637c5b2abe0SLewanczyk, Dawid 638c5b2abe0SLewanczyk, Dawid provider.getHostState(asyncResp); 639c5b2abe0SLewanczyk, Dawid provider.getComputerSystem(asyncResp, name); 640c5b2abe0SLewanczyk, Dawid 641c5b2abe0SLewanczyk, Dawid if (dbusLedState.empty()) { 642c5b2abe0SLewanczyk, Dawid messages::addMessageToJsonRoot( 64355c7b7a2SEd Tanous res.jsonValue, 644c5b2abe0SLewanczyk, Dawid messages::propertyValueNotInList(*reqLedState, "IndicatorLED")); 645c5b2abe0SLewanczyk, Dawid } else { 646c5b2abe0SLewanczyk, Dawid // Update led group 64755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led group."; 64855c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 649c5b2abe0SLewanczyk, Dawid [&, asyncResp{std::move(asyncResp)} ]( 650c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 651c5b2abe0SLewanczyk, Dawid if (ec) { 65255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 653c5b2abe0SLewanczyk, Dawid asyncResp->setErrorStatus(); 654c5b2abe0SLewanczyk, Dawid return; 655c5b2abe0SLewanczyk, Dawid } 65655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led group update done."; 657c5b2abe0SLewanczyk, Dawid }, 658c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.GroupManager", 659c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/groups/enclosure_identify", 660c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 661c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Group", "Asserted", 662c5b2abe0SLewanczyk, Dawid sdbusplus::message::variant<bool>( 663c5b2abe0SLewanczyk, Dawid (dbusLedState == "Off" ? false : true))); 664c5b2abe0SLewanczyk, Dawid // Update identify led status 66555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection."; 66655c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 667c5b2abe0SLewanczyk, Dawid [&, asyncResp{std::move(asyncResp)} ]( 668c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 669c5b2abe0SLewanczyk, Dawid if (ec) { 67055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 671c5b2abe0SLewanczyk, Dawid asyncResp->setErrorStatus(); 672c5b2abe0SLewanczyk, Dawid return; 673c5b2abe0SLewanczyk, Dawid } 67455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led state update done."; 67555c7b7a2SEd Tanous res.jsonValue["IndicatorLED"] = *reqLedState; 676c5b2abe0SLewanczyk, Dawid }, 677c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 678c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 679c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 680c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical", "State", 681c5b2abe0SLewanczyk, Dawid sdbusplus::message::variant<std::string>( 682c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical.Action." + dbusLedState)); 683c5b2abe0SLewanczyk, Dawid } 684c5b2abe0SLewanczyk, Dawid } 685c5b2abe0SLewanczyk, Dawid }; 686c5b2abe0SLewanczyk, Dawid } // namespace redfish 687