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. 72c5b2abe0SLewanczyk, Dawid std::vector<std::string> board_list; 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. 78c5b2abe0SLewanczyk, Dawid callback(false, board_list); 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) { 84c5b2abe0SLewanczyk, Dawid std::size_t last_pos = objpath.rfind("/"); 85c5b2abe0SLewanczyk, Dawid if (last_pos != std::string::npos) { 86c5b2abe0SLewanczyk, Dawid board_list.emplace_back(objpath.substr(last_pos + 1)); 87c5b2abe0SLewanczyk, Dawid } 88c5b2abe0SLewanczyk, Dawid } 89c5b2abe0SLewanczyk, Dawid // Finally make a callback with useful data 90c5b2abe0SLewanczyk, Dawid callback(true, board_list); 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 { 203*a434f2bdSEd Tanous BMCWEB_LOG_ERROR 204*a434f2bdSEd 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( 335*a434f2bdSEd Tanous [aResp{std::move(aResp)}, &callback]( 336*a434f2bdSEd Tanous const boost::system::error_code &ec, 337*a434f2bdSEd Tanous 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( 375*a434f2bdSEd Tanous [aResp{std::move(aResp)}, &callback](const boost::system::error_code ec, 376c5b2abe0SLewanczyk, Dawid const PropertiesType &properties) { 377c5b2abe0SLewanczyk, Dawid if (ec) { 37855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 379c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 380c5b2abe0SLewanczyk, Dawid return; 381c5b2abe0SLewanczyk, Dawid } 38255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() << "led properties."; 383c5b2abe0SLewanczyk, Dawid std::string output; 384c5b2abe0SLewanczyk, Dawid for (const auto &property : properties) { 385c5b2abe0SLewanczyk, Dawid if (property.first == "State") { 386c5b2abe0SLewanczyk, Dawid const std::string *s = 38755c7b7a2SEd Tanous mapbox::getPtr<std::string>(property.second); 388c5b2abe0SLewanczyk, Dawid if (nullptr != s) { 38955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Identify Led State: " << *s; 390c5b2abe0SLewanczyk, Dawid const auto pos = s->rfind('.'); 391c5b2abe0SLewanczyk, Dawid if (pos != std::string::npos) { 392c5b2abe0SLewanczyk, Dawid auto led = s->substr(pos + 1); 393c5b2abe0SLewanczyk, Dawid for (const std::pair<const char *, const char *> &p : 394c5b2abe0SLewanczyk, Dawid std::array<std::pair<const char *, const char *>, 3>{ 395c5b2abe0SLewanczyk, Dawid {{"On", "Lit"}, 396c5b2abe0SLewanczyk, Dawid {"Blink", "Blinking"}, 397c5b2abe0SLewanczyk, Dawid {"Off", "Off"}}}) { 398c5b2abe0SLewanczyk, Dawid if (led == p.first) { 399c5b2abe0SLewanczyk, Dawid output = p.second; 400c5b2abe0SLewanczyk, Dawid } 401c5b2abe0SLewanczyk, Dawid } 402c5b2abe0SLewanczyk, Dawid } 403c5b2abe0SLewanczyk, Dawid } 404c5b2abe0SLewanczyk, Dawid } 405c5b2abe0SLewanczyk, Dawid } 406c5b2abe0SLewanczyk, Dawid callback(output, aResp); 407c5b2abe0SLewanczyk, Dawid }, 408c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 409c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 410c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "GetAll", 411c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical"); 412c5b2abe0SLewanczyk, Dawid } 413c5b2abe0SLewanczyk, Dawid 414c5b2abe0SLewanczyk, Dawid /** 415c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 416c5b2abe0SLewanczyk, Dawid * 417c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 418c5b2abe0SLewanczyk, Dawid * 419c5b2abe0SLewanczyk, Dawid * @return None. 420c5b2abe0SLewanczyk, Dawid */ 421c5b2abe0SLewanczyk, Dawid void getHostState(std::shared_ptr<SystemAsyncResp> aResp) { 42255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 42355c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 424c5b2abe0SLewanczyk, Dawid [aResp{std::move(aResp)}](const boost::system::error_code ec, 425c5b2abe0SLewanczyk, Dawid const PropertiesType &properties) { 426c5b2abe0SLewanczyk, Dawid if (ec) { 42755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 428c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 429c5b2abe0SLewanczyk, Dawid return; 430c5b2abe0SLewanczyk, Dawid } 43155c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() << "host properties."; 432c5b2abe0SLewanczyk, Dawid for (const auto &property : properties) { 433c5b2abe0SLewanczyk, Dawid if (property.first == "CurrentHostState") { 434c5b2abe0SLewanczyk, Dawid const std::string *s = 43555c7b7a2SEd Tanous mapbox::getPtr<const std::string>(property.second); 43655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Host state: " << *s; 437c5b2abe0SLewanczyk, Dawid if (nullptr != s) { 438c5b2abe0SLewanczyk, Dawid const auto pos = s->rfind('.'); 439c5b2abe0SLewanczyk, Dawid if (pos != std::string::npos) { 440c5b2abe0SLewanczyk, Dawid // Verify Host State 441c5b2abe0SLewanczyk, Dawid if (s->substr(pos + 1) == "Running") { 44255c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 44355c7b7a2SEd Tanous aResp->res.jsonValue["Status"]["State"] = "Enabled"; 444c5b2abe0SLewanczyk, Dawid } else { 44555c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 44655c7b7a2SEd Tanous aResp->res.jsonValue["Status"]["State"] = "Disabled"; 447c5b2abe0SLewanczyk, Dawid } 448c5b2abe0SLewanczyk, Dawid } 449c5b2abe0SLewanczyk, Dawid } 450c5b2abe0SLewanczyk, Dawid } 451c5b2abe0SLewanczyk, Dawid } 452c5b2abe0SLewanczyk, Dawid }, 453c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 454c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "GetAll", 455c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.State.Host"); 456c5b2abe0SLewanczyk, Dawid } 457c5b2abe0SLewanczyk, Dawid }; 458c5b2abe0SLewanczyk, Dawid 459c5b2abe0SLewanczyk, Dawid /** 460c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 461c5b2abe0SLewanczyk, Dawid * Schema 462c5b2abe0SLewanczyk, Dawid */ 463c5b2abe0SLewanczyk, Dawid class SystemsCollection : public Node { 464c5b2abe0SLewanczyk, Dawid public: 465c5b2abe0SLewanczyk, Dawid SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/") { 466c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = 467c5b2abe0SLewanczyk, Dawid "#ComputerSystemCollection.ComputerSystemCollection"; 468c5b2abe0SLewanczyk, Dawid Node::json["@odata.id"] = "/redfish/v1/Systems"; 469c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 470c5b2abe0SLewanczyk, Dawid "/redfish/v1/" 471c5b2abe0SLewanczyk, Dawid "$metadata#ComputerSystemCollection.ComputerSystemCollection"; 472c5b2abe0SLewanczyk, Dawid Node::json["Name"] = "Computer System Collection"; 473c5b2abe0SLewanczyk, Dawid 474c5b2abe0SLewanczyk, Dawid entityPrivileges = { 475c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 476c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 477c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 478c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 479c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 480c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 481c5b2abe0SLewanczyk, Dawid } 482c5b2abe0SLewanczyk, Dawid 483c5b2abe0SLewanczyk, Dawid private: 484c5b2abe0SLewanczyk, Dawid /** 485c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 486c5b2abe0SLewanczyk, Dawid */ 48755c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 488c5b2abe0SLewanczyk, Dawid const std::vector<std::string> ¶ms) override { 489c5b2abe0SLewanczyk, Dawid // Get board list, and call the below callback for JSON preparation 490c5b2abe0SLewanczyk, Dawid provider.getBaseboardList( 491c5b2abe0SLewanczyk, Dawid [&](const bool &success, const std::vector<std::string> &output) { 492c5b2abe0SLewanczyk, Dawid if (success) { 493c5b2abe0SLewanczyk, Dawid // ... prepare json array with appropriate @odata.id links 494c5b2abe0SLewanczyk, Dawid nlohmann::json boardArray = nlohmann::json::array(); 495c5b2abe0SLewanczyk, Dawid for (const std::string &board_item : output) { 496c5b2abe0SLewanczyk, Dawid boardArray.push_back( 497c5b2abe0SLewanczyk, Dawid {{"@odata.id", "/redfish/v1/Systems/" + board_item}}); 498c5b2abe0SLewanczyk, Dawid } 499c5b2abe0SLewanczyk, Dawid // Then attach members, count size and return, 500c5b2abe0SLewanczyk, Dawid Node::json["Members"] = boardArray; 501c5b2abe0SLewanczyk, Dawid Node::json["Members@odata.count"] = boardArray.size(); 50255c7b7a2SEd Tanous res.jsonValue = Node::json; 503c5b2abe0SLewanczyk, Dawid } else { 504c5b2abe0SLewanczyk, Dawid // ... otherwise, return INTERNALL ERROR 505c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 506c5b2abe0SLewanczyk, Dawid } 507c5b2abe0SLewanczyk, Dawid res.end(); 508c5b2abe0SLewanczyk, Dawid }); 509c5b2abe0SLewanczyk, Dawid } 510c5b2abe0SLewanczyk, Dawid 511c5b2abe0SLewanczyk, Dawid OnDemandSystemsProvider provider; 512c5b2abe0SLewanczyk, Dawid }; 513c5b2abe0SLewanczyk, Dawid 514c5b2abe0SLewanczyk, Dawid /** 515c5b2abe0SLewanczyk, Dawid * Systems override class for delivering ComputerSystems Schema 516c5b2abe0SLewanczyk, Dawid */ 517c5b2abe0SLewanczyk, Dawid class Systems : public Node { 518c5b2abe0SLewanczyk, Dawid public: 519c5b2abe0SLewanczyk, Dawid /* 520c5b2abe0SLewanczyk, Dawid * Default Constructor 521c5b2abe0SLewanczyk, Dawid */ 522c5b2abe0SLewanczyk, Dawid Systems(CrowApp &app) 523c5b2abe0SLewanczyk, Dawid : Node(app, "/redfish/v1/Systems/<str>/", std::string()) { 524c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem"; 525c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 526c5b2abe0SLewanczyk, Dawid "/redfish/v1/$metadata#ComputerSystem.ComputerSystem"; 527c5b2abe0SLewanczyk, Dawid Node::json["SystemType"] = "Physical"; 528c5b2abe0SLewanczyk, Dawid Node::json["Description"] = "Computer System"; 529c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideEnabled"] = 530c5b2abe0SLewanczyk, Dawid "Disabled"; // TODO(Dawid), get real boot data 531c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideTarget"] = 532c5b2abe0SLewanczyk, Dawid "None"; // TODO(Dawid), get real boot data 533c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideMode"] = 534c5b2abe0SLewanczyk, Dawid "Legacy"; // TODO(Dawid), get real boot data 535c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 536c5b2abe0SLewanczyk, Dawid "None", "Pxe", "Hdd", "Cd", 537c5b2abe0SLewanczyk, Dawid "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot data 538c5b2abe0SLewanczyk, Dawid Node::json["ProcessorSummary"]["Count"] = int(0); 539c5b2abe0SLewanczyk, Dawid Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled"; 540c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0); 541c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["Status"]["State"] = "Disabled"; 542c5b2abe0SLewanczyk, Dawid 543c5b2abe0SLewanczyk, Dawid entityPrivileges = { 544c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 545c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 546c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 547c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 548c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 549c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 550c5b2abe0SLewanczyk, Dawid } 551c5b2abe0SLewanczyk, Dawid 552c5b2abe0SLewanczyk, Dawid private: 553c5b2abe0SLewanczyk, Dawid OnDemandSystemsProvider provider; 554c5b2abe0SLewanczyk, Dawid 555c5b2abe0SLewanczyk, Dawid /** 556c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 557c5b2abe0SLewanczyk, Dawid */ 55855c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 559c5b2abe0SLewanczyk, Dawid const std::vector<std::string> ¶ms) override { 560c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 561c5b2abe0SLewanczyk, Dawid // impossible 562c5b2abe0SLewanczyk, Dawid if (params.size() != 1) { 563c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 564c5b2abe0SLewanczyk, Dawid res.end(); 565c5b2abe0SLewanczyk, Dawid return; 566c5b2abe0SLewanczyk, Dawid } 567c5b2abe0SLewanczyk, Dawid 568c5b2abe0SLewanczyk, Dawid const std::string &name = params[0]; 569c5b2abe0SLewanczyk, Dawid 57055c7b7a2SEd Tanous res.jsonValue = Node::json; 57155c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 572c5b2abe0SLewanczyk, Dawid 573c5b2abe0SLewanczyk, Dawid auto asyncResp = std::make_shared<SystemAsyncResp>(res); 574c5b2abe0SLewanczyk, Dawid 575c5b2abe0SLewanczyk, Dawid provider.getLedGroupIdentify( 576c5b2abe0SLewanczyk, Dawid asyncResp, [&](const bool &asserted, 577c5b2abe0SLewanczyk, Dawid const std::shared_ptr<SystemAsyncResp> &aResp) { 578c5b2abe0SLewanczyk, Dawid if (asserted) { 579c5b2abe0SLewanczyk, Dawid // If led group is asserted, then another call is needed to 580c5b2abe0SLewanczyk, Dawid // get led status 581c5b2abe0SLewanczyk, Dawid provider.getLedIdentify( 582c5b2abe0SLewanczyk, Dawid aResp, [](const std::string &ledStatus, 583c5b2abe0SLewanczyk, Dawid const std::shared_ptr<SystemAsyncResp> &aResp) { 584c5b2abe0SLewanczyk, Dawid if (!ledStatus.empty()) { 58555c7b7a2SEd Tanous aResp->res.jsonValue["IndicatorLED"] = ledStatus; 586c5b2abe0SLewanczyk, Dawid } 587c5b2abe0SLewanczyk, Dawid }); 588c5b2abe0SLewanczyk, Dawid } else { 58955c7b7a2SEd Tanous aResp->res.jsonValue["IndicatorLED"] = "Off"; 590c5b2abe0SLewanczyk, Dawid } 591c5b2abe0SLewanczyk, Dawid }); 592c5b2abe0SLewanczyk, Dawid provider.getComputerSystem(asyncResp, name); 593c5b2abe0SLewanczyk, Dawid provider.getHostState(asyncResp); 594c5b2abe0SLewanczyk, Dawid } 595c5b2abe0SLewanczyk, Dawid 59655c7b7a2SEd Tanous void doPatch(crow::Response &res, const crow::Request &req, 597c5b2abe0SLewanczyk, Dawid const std::vector<std::string> ¶ms) override { 598c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 599c5b2abe0SLewanczyk, Dawid // impossible 600c5b2abe0SLewanczyk, Dawid if (params.size() != 1) { 601c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 602c5b2abe0SLewanczyk, Dawid res.end(); 603c5b2abe0SLewanczyk, Dawid return; 604c5b2abe0SLewanczyk, Dawid } 605c5b2abe0SLewanczyk, Dawid // Parse JSON request body 606c5b2abe0SLewanczyk, Dawid nlohmann::json patch; 607c5b2abe0SLewanczyk, Dawid if (!json_util::processJsonFromRequest(res, req, patch)) { 608c5b2abe0SLewanczyk, Dawid return; 609c5b2abe0SLewanczyk, Dawid } 610c5b2abe0SLewanczyk, Dawid // Find key with new led value 611c5b2abe0SLewanczyk, Dawid const std::string &name = params[0]; 612c5b2abe0SLewanczyk, Dawid const std::string *reqLedState = nullptr; 613c5b2abe0SLewanczyk, Dawid json_util::Result r = json_util::getString( 614c5b2abe0SLewanczyk, Dawid "IndicatorLED", patch, reqLedState, 615c5b2abe0SLewanczyk, Dawid static_cast<int>(json_util::MessageSetting::TYPE_ERROR) | 616c5b2abe0SLewanczyk, Dawid static_cast<int>(json_util::MessageSetting::MISSING), 61755c7b7a2SEd Tanous res.jsonValue, std::string("/" + name + "/IndicatorLED")); 618c5b2abe0SLewanczyk, Dawid if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr)) { 619c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::bad_request); 620c5b2abe0SLewanczyk, Dawid res.end(); 621c5b2abe0SLewanczyk, Dawid return; 622c5b2abe0SLewanczyk, Dawid } 623c5b2abe0SLewanczyk, Dawid // Verify key value 624c5b2abe0SLewanczyk, Dawid std::string dbusLedState; 625c5b2abe0SLewanczyk, Dawid for (const auto &p : boost::container::flat_map<const char *, const char *>{ 626c5b2abe0SLewanczyk, Dawid {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}}) { 627c5b2abe0SLewanczyk, Dawid if (*reqLedState == p.second) { 628c5b2abe0SLewanczyk, Dawid dbusLedState = p.first; 629c5b2abe0SLewanczyk, Dawid } 630c5b2abe0SLewanczyk, Dawid } 631c5b2abe0SLewanczyk, Dawid 632c5b2abe0SLewanczyk, Dawid // Update led status 633c5b2abe0SLewanczyk, Dawid auto asyncResp = std::make_shared<SystemAsyncResp>(res); 63455c7b7a2SEd Tanous res.jsonValue = Node::json; 63555c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 636c5b2abe0SLewanczyk, Dawid 637c5b2abe0SLewanczyk, Dawid provider.getHostState(asyncResp); 638c5b2abe0SLewanczyk, Dawid provider.getComputerSystem(asyncResp, name); 639c5b2abe0SLewanczyk, Dawid 640c5b2abe0SLewanczyk, Dawid if (dbusLedState.empty()) { 641c5b2abe0SLewanczyk, Dawid messages::addMessageToJsonRoot( 64255c7b7a2SEd Tanous res.jsonValue, 643c5b2abe0SLewanczyk, Dawid messages::propertyValueNotInList(*reqLedState, "IndicatorLED")); 644c5b2abe0SLewanczyk, Dawid } else { 645c5b2abe0SLewanczyk, Dawid // Update led group 64655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led group."; 64755c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 648c5b2abe0SLewanczyk, Dawid [&, asyncResp{std::move(asyncResp)}]( 649c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 650c5b2abe0SLewanczyk, Dawid if (ec) { 65155c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 652c5b2abe0SLewanczyk, Dawid asyncResp->setErrorStatus(); 653c5b2abe0SLewanczyk, Dawid return; 654c5b2abe0SLewanczyk, Dawid } 65555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led group update done."; 656c5b2abe0SLewanczyk, Dawid }, 657c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.GroupManager", 658c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/groups/enclosure_identify", 659c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 660c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Group", "Asserted", 661c5b2abe0SLewanczyk, Dawid sdbusplus::message::variant<bool>( 662c5b2abe0SLewanczyk, Dawid (dbusLedState == "Off" ? false : true))); 663c5b2abe0SLewanczyk, Dawid // Update identify led status 66455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection."; 66555c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 666c5b2abe0SLewanczyk, Dawid [&, asyncResp{std::move(asyncResp)}]( 667c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 668c5b2abe0SLewanczyk, Dawid if (ec) { 66955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 670c5b2abe0SLewanczyk, Dawid asyncResp->setErrorStatus(); 671c5b2abe0SLewanczyk, Dawid return; 672c5b2abe0SLewanczyk, Dawid } 67355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led state update done."; 67455c7b7a2SEd Tanous res.jsonValue["IndicatorLED"] = *reqLedState; 675c5b2abe0SLewanczyk, Dawid }, 676c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 677c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 678c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 679c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical", "State", 680c5b2abe0SLewanczyk, Dawid sdbusplus::message::variant<std::string>( 681c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical.Action." + dbusLedState)); 682c5b2abe0SLewanczyk, Dawid } 683c5b2abe0SLewanczyk, Dawid } 684c5b2abe0SLewanczyk, Dawid }; 685c5b2abe0SLewanczyk, Dawid } // namespace redfish 686