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 181abe55efSEd Tanous #include "boost/container/flat_map.hpp" 191abe55efSEd Tanous #include "node.hpp" 201abe55efSEd Tanous 21c5b2abe0SLewanczyk, Dawid #include <error_messages.hpp> 22c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp> 23c5b2abe0SLewanczyk, Dawid 241abe55efSEd Tanous namespace redfish 251abe55efSEd Tanous { 26c5b2abe0SLewanczyk, Dawid 27c5b2abe0SLewanczyk, Dawid /** 28c5b2abe0SLewanczyk, Dawid * OnDemandSystemsProvider 29c5b2abe0SLewanczyk, Dawid * Board provider class that retrieves data directly from dbus, before seting 30c5b2abe0SLewanczyk, Dawid * it into JSON output. This does not cache any data. 31c5b2abe0SLewanczyk, Dawid * 32c5b2abe0SLewanczyk, Dawid * Class can be a good example on how to scale different data providing 33c5b2abe0SLewanczyk, Dawid * solutions to produce single schema output. 34c5b2abe0SLewanczyk, Dawid * 35c5b2abe0SLewanczyk, Dawid * TODO(Pawel) 36c5b2abe0SLewanczyk, Dawid * This perhaps shall be different file, which has to be chosen on compile time 37c5b2abe0SLewanczyk, Dawid * depending on OEM needs 38c5b2abe0SLewanczyk, Dawid */ 391abe55efSEd Tanous class OnDemandSystemsProvider 401abe55efSEd Tanous { 41c5b2abe0SLewanczyk, Dawid public: 42c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 431abe55efSEd Tanous void getBaseboardList(CallbackFunc &&callback) 441abe55efSEd Tanous { 4555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get list of available boards."; 4655c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 471abe55efSEd Tanous [callback{std::move(callback)}]( 481abe55efSEd Tanous const boost::system::error_code ec, 49c5b2abe0SLewanczyk, Dawid const std::vector<std::string> &resp) { 501abe55efSEd Tanous // Callback requires vector<string> to retrieve all available 511abe55efSEd Tanous // board list. 52d76323e5SEd Tanous std::vector<std::string> boardList; 531abe55efSEd Tanous if (ec) 541abe55efSEd Tanous { 551abe55efSEd Tanous // Something wrong on DBus, the error_code is not important 561abe55efSEd Tanous // at this moment, just return success=false, and empty 571abe55efSEd Tanous // output. Since size of vector may vary depending on 581abe55efSEd Tanous // information from Entity Manager, and empty output could 591abe55efSEd Tanous // not be treated same way as error. 60d76323e5SEd Tanous callback(false, boardList); 61c5b2abe0SLewanczyk, Dawid return; 62c5b2abe0SLewanczyk, Dawid } 6355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards."; 64c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 651abe55efSEd Tanous for (const std::string &objpath : resp) 661abe55efSEd Tanous { 67d76323e5SEd Tanous std::size_t lastPos = objpath.rfind("/"); 681abe55efSEd Tanous if (lastPos != std::string::npos) 691abe55efSEd Tanous { 70d76323e5SEd Tanous boardList.emplace_back(objpath.substr(lastPos + 1)); 71c5b2abe0SLewanczyk, Dawid } 72c5b2abe0SLewanczyk, Dawid } 73c5b2abe0SLewanczyk, Dawid // Finally make a callback with useful data 74d76323e5SEd Tanous callback(true, boardList); 75c5b2abe0SLewanczyk, Dawid }, 76c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 77c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 78c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", 79c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/inventory", int32_t(0), 80c5b2abe0SLewanczyk, Dawid std::array<const char *, 1>{ 81c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.Board"}); 82c5b2abe0SLewanczyk, Dawid }; 83c5b2abe0SLewanczyk, Dawid 84c5b2abe0SLewanczyk, Dawid /** 85c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 86c5b2abe0SLewanczyk, Dawid * 87c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls 88c5b2abe0SLewanczyk, Dawid * @param[in] name Computer system name from request 89c5b2abe0SLewanczyk, Dawid * 90c5b2abe0SLewanczyk, Dawid * @return None. 91c5b2abe0SLewanczyk, Dawid */ 92*a0803efaSEd Tanous void getComputerSystem(std::shared_ptr<AsyncResp> aResp, 931abe55efSEd Tanous const std::string &name) 941abe55efSEd Tanous { 95c5b2abe0SLewanczyk, Dawid const std::array<const char *, 5> interfaces = { 96c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Decorator.Asset", 97c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.Cpu", 98c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.Dimm", 99c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.System", 100c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Common.UUID", 101c5b2abe0SLewanczyk, Dawid }; 10255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 10355c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 104c5b2abe0SLewanczyk, Dawid [name, aResp{std::move(aResp)}]( 105c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 106c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 1071abe55efSEd Tanous std::string, std::vector<std::pair< 1081abe55efSEd Tanous std::string, std::vector<std::string>>>>> 109c5b2abe0SLewanczyk, Dawid &subtree) { 1101abe55efSEd Tanous if (ec) 1111abe55efSEd Tanous { 11255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 113*a0803efaSEd Tanous aResp->res.result( 114*a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 115c5b2abe0SLewanczyk, Dawid return; 116c5b2abe0SLewanczyk, Dawid } 117c5b2abe0SLewanczyk, Dawid bool foundName = false; 118c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 1191abe55efSEd Tanous for (const std::pair< 1201abe55efSEd Tanous std::string, 1211abe55efSEd Tanous std::vector< 1221abe55efSEd Tanous std::pair<std::string, std::vector<std::string>>>> 1231abe55efSEd Tanous &object : subtree) 1241abe55efSEd Tanous { 125c5b2abe0SLewanczyk, Dawid const std::string &path = object.first; 12655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 1271abe55efSEd Tanous const std::vector< 1281abe55efSEd Tanous std::pair<std::string, std::vector<std::string>>> 129c5b2abe0SLewanczyk, Dawid &connectionNames = object.second; 1301abe55efSEd Tanous if (connectionNames.size() < 1) 1311abe55efSEd Tanous { 132c5b2abe0SLewanczyk, Dawid continue; 133c5b2abe0SLewanczyk, Dawid } 134c5b2abe0SLewanczyk, Dawid // Check if computer system exist 1351abe55efSEd Tanous if (boost::ends_with(path, name)) 1361abe55efSEd Tanous { 137c5b2abe0SLewanczyk, Dawid foundName = true; 13855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Found name: " << name; 1391abe55efSEd Tanous const std::string connectionName = 1401abe55efSEd Tanous connectionNames[0].first; 14155c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 142c5b2abe0SLewanczyk, Dawid [aResp, name(std::string(name))]( 143c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 1441abe55efSEd Tanous const std::vector< 1451abe55efSEd Tanous std::pair<std::string, VariantType>> 146c5b2abe0SLewanczyk, Dawid &propertiesList) { 1471abe55efSEd Tanous if (ec) 1481abe55efSEd Tanous { 1491abe55efSEd Tanous BMCWEB_LOG_ERROR << "DBUS response error: " 1501abe55efSEd Tanous << ec; 151*a0803efaSEd Tanous aResp->res.result( 152*a0803efaSEd Tanous boost::beast::http::status:: 153*a0803efaSEd Tanous internal_server_error); 154c5b2abe0SLewanczyk, Dawid return; 155c5b2abe0SLewanczyk, Dawid } 1561abe55efSEd Tanous BMCWEB_LOG_DEBUG << "Got " 1571abe55efSEd Tanous << propertiesList.size() 158c5b2abe0SLewanczyk, Dawid << "properties for system"; 1591abe55efSEd Tanous for (const std::pair<std::string, VariantType> 1601abe55efSEd Tanous &property : propertiesList) 1611abe55efSEd Tanous { 162c5b2abe0SLewanczyk, Dawid const std::string *value = 1631abe55efSEd Tanous mapbox::getPtr<const std::string>( 1641abe55efSEd Tanous property.second); 1651abe55efSEd Tanous if (value != nullptr) 1661abe55efSEd Tanous { 1671abe55efSEd Tanous aResp->res.jsonValue[property.first] = 1681abe55efSEd Tanous *value; 169c5b2abe0SLewanczyk, Dawid } 170c5b2abe0SLewanczyk, Dawid } 17155c7b7a2SEd Tanous aResp->res.jsonValue["Name"] = name; 17255c7b7a2SEd Tanous aResp->res.jsonValue["Id"] = 17355c7b7a2SEd Tanous aResp->res.jsonValue["SerialNumber"]; 174c5b2abe0SLewanczyk, Dawid }, 1751abe55efSEd Tanous connectionName, path, 1761abe55efSEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 1771abe55efSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset"); 1781abe55efSEd Tanous } 1791abe55efSEd Tanous else 1801abe55efSEd Tanous { 1811abe55efSEd Tanous // This is not system, so check if it's cpu, dimm, UUID 1821abe55efSEd Tanous // or BiosVer 1831abe55efSEd Tanous for (auto const &s : connectionNames) 1841abe55efSEd Tanous { 1851abe55efSEd Tanous for (auto const &i : s.second) 1861abe55efSEd Tanous { 1871abe55efSEd Tanous if (boost::ends_with(i, "Dimm")) 1881abe55efSEd Tanous { 1891abe55efSEd Tanous BMCWEB_LOG_DEBUG 1901abe55efSEd Tanous << "Found Dimm, now get it properties."; 19155c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 1921abe55efSEd Tanous [&, aResp]( 1931abe55efSEd Tanous const boost::system::error_code ec, 194c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 1951abe55efSEd Tanous std::string, VariantType>> 1961abe55efSEd Tanous &properties) { 1971abe55efSEd Tanous if (ec) 1981abe55efSEd Tanous { 1991abe55efSEd Tanous BMCWEB_LOG_ERROR 2001abe55efSEd Tanous << "DBUS response error " 2011abe55efSEd Tanous << ec; 202*a0803efaSEd Tanous aResp->res.result( 203*a0803efaSEd Tanous boost::beast::http::status:: 204*a0803efaSEd Tanous internal_server_error); 205c5b2abe0SLewanczyk, Dawid return; 206c5b2abe0SLewanczyk, Dawid } 2071abe55efSEd Tanous BMCWEB_LOG_DEBUG 2081abe55efSEd Tanous << "Got " << properties.size() 209c5b2abe0SLewanczyk, Dawid << "Dimm properties."; 2101abe55efSEd Tanous for (const auto &p : properties) 2111abe55efSEd Tanous { 2121abe55efSEd Tanous if (p.first == "MemorySize") 2131abe55efSEd Tanous { 214c5b2abe0SLewanczyk, Dawid const std::string *value = 2151abe55efSEd Tanous mapbox::getPtr< 2161abe55efSEd Tanous const std::string>( 2171abe55efSEd Tanous p.second); 2181abe55efSEd Tanous if ((value != nullptr) && 2191abe55efSEd Tanous (*value != "NULL")) 2201abe55efSEd Tanous { 221c5b2abe0SLewanczyk, Dawid // Remove units char 222c5b2abe0SLewanczyk, Dawid int32_t unitCoeff; 2231abe55efSEd Tanous if (boost::ends_with( 2241abe55efSEd Tanous *value, "MB")) 2251abe55efSEd Tanous { 226c5b2abe0SLewanczyk, Dawid unitCoeff = 1000; 2271abe55efSEd Tanous } 2281abe55efSEd Tanous else if (boost:: 2291abe55efSEd Tanous ends_with( 2301abe55efSEd Tanous *value, 2311abe55efSEd Tanous "KB")) 2321abe55efSEd Tanous { 233c5b2abe0SLewanczyk, Dawid unitCoeff = 1000000; 2341abe55efSEd Tanous } 2351abe55efSEd Tanous else 2361abe55efSEd Tanous { 237a434f2bdSEd Tanous BMCWEB_LOG_ERROR 2381abe55efSEd Tanous << "Unsupported" 2391abe55efSEd Tanous " memory " 2401abe55efSEd Tanous "units"; 241*a0803efaSEd Tanous aResp->res.result( 242*a0803efaSEd Tanous boost::beast:: 243*a0803efaSEd Tanous http::status:: 244*a0803efaSEd Tanous internal_server_error); 245c5b2abe0SLewanczyk, Dawid return; 246c5b2abe0SLewanczyk, Dawid } 247c5b2abe0SLewanczyk, Dawid 2481abe55efSEd Tanous auto memSize = 2491abe55efSEd Tanous boost::lexical_cast< 2501abe55efSEd Tanous int>(value->substr( 2511abe55efSEd Tanous 0, 2521abe55efSEd Tanous value->length() - 2531abe55efSEd Tanous 2)); 2541abe55efSEd Tanous aResp->res.jsonValue 2551abe55efSEd Tanous ["TotalSystemMemory" 2561abe55efSEd Tanous "GiB"] += 257c5b2abe0SLewanczyk, Dawid memSize * unitCoeff; 2581abe55efSEd Tanous aResp->res.jsonValue 2591abe55efSEd Tanous ["MemorySummary"] 2601abe55efSEd Tanous ["Status"] 2611abe55efSEd Tanous ["State"] = 2621abe55efSEd Tanous "Enabled"; 263c5b2abe0SLewanczyk, Dawid } 264c5b2abe0SLewanczyk, Dawid } 265c5b2abe0SLewanczyk, Dawid } 266c5b2abe0SLewanczyk, Dawid }, 2671abe55efSEd Tanous s.first, path, 2681abe55efSEd Tanous "org.freedesktop.DBus.Properties", 2691abe55efSEd Tanous "GetAll", 2701abe55efSEd Tanous "xyz.openbmc_project.Inventory.Item." 2711abe55efSEd Tanous "Dimm"); 2721abe55efSEd Tanous } 2731abe55efSEd Tanous else if (boost::ends_with(i, "Cpu")) 2741abe55efSEd Tanous { 2751abe55efSEd Tanous BMCWEB_LOG_DEBUG 2761abe55efSEd Tanous << "Found Cpu, now get it properties."; 277*a0803efaSEd Tanous crow::connections::systemBus->async_method_call( 2781abe55efSEd Tanous [&, aResp]( 279*a0803efaSEd Tanous const boost::system::error_code ec, 280c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 2811abe55efSEd Tanous std::string, VariantType>> 2821abe55efSEd Tanous &properties) { 2831abe55efSEd Tanous if (ec) 2841abe55efSEd Tanous { 2851abe55efSEd Tanous BMCWEB_LOG_ERROR 286*a0803efaSEd Tanous << "DBUS response error " 2871abe55efSEd Tanous << ec; 288*a0803efaSEd Tanous aResp->res.result( 289*a0803efaSEd Tanous boost::beast::http::status:: 290*a0803efaSEd Tanous internal_server_error); 291c5b2abe0SLewanczyk, Dawid return; 292c5b2abe0SLewanczyk, Dawid } 2931abe55efSEd Tanous BMCWEB_LOG_DEBUG 294*a0803efaSEd Tanous << "Got " << properties.size() 295c5b2abe0SLewanczyk, Dawid << "Cpu properties."; 2961abe55efSEd Tanous for (const auto &p : properties) 2971abe55efSEd Tanous { 2981abe55efSEd Tanous if (p.first == 2991abe55efSEd Tanous "ProcessorFamily") 3001abe55efSEd Tanous { 301*a0803efaSEd Tanous const std::string *value = 3021abe55efSEd Tanous mapbox::getPtr< 303*a0803efaSEd Tanous const std::string>( 3041abe55efSEd Tanous p.second); 3051abe55efSEd Tanous if (value != nullptr) 3061abe55efSEd Tanous { 3071abe55efSEd Tanous aResp->res.jsonValue 308*a0803efaSEd Tanous ["ProcessorSummary"] 3091abe55efSEd Tanous ["Count"] = 310c5b2abe0SLewanczyk, Dawid aResp->res 3111abe55efSEd Tanous .jsonValue 312*a0803efaSEd Tanous ["Processor" 313*a0803efaSEd Tanous "Summary"] 314*a0803efaSEd Tanous ["Count"] 315*a0803efaSEd Tanous .get<int>() + 316c5b2abe0SLewanczyk, Dawid 1; 3171abe55efSEd Tanous aResp->res.jsonValue 318*a0803efaSEd Tanous ["ProcessorSummary"] 3191abe55efSEd Tanous ["Status"] 3201abe55efSEd Tanous ["State"] = 321c5b2abe0SLewanczyk, Dawid "Enabled"; 3221abe55efSEd Tanous aResp->res.jsonValue 323*a0803efaSEd Tanous ["ProcessorSummary"] 324*a0803efaSEd Tanous ["Model"] = *value; 325c5b2abe0SLewanczyk, Dawid } 326c5b2abe0SLewanczyk, Dawid } 327c5b2abe0SLewanczyk, Dawid } 328c5b2abe0SLewanczyk, Dawid }, 3291abe55efSEd Tanous s.first, path, 3301abe55efSEd Tanous "org.freedesktop.DBus.Properties", 3311abe55efSEd Tanous "GetAll", 332*a0803efaSEd Tanous "xyz.openbmc_project.Inventory.Item." 333*a0803efaSEd Tanous "Cpu"); 3341abe55efSEd Tanous } 3351abe55efSEd Tanous else if (boost::ends_with(i, "UUID")) 3361abe55efSEd Tanous { 3371abe55efSEd Tanous BMCWEB_LOG_DEBUG 3381abe55efSEd Tanous << "Found UUID, now get it properties."; 33955c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 3401abe55efSEd Tanous [aResp]( 3411abe55efSEd Tanous const boost::system::error_code ec, 342c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 3431abe55efSEd Tanous std::string, VariantType>> 3441abe55efSEd Tanous &properties) { 3451abe55efSEd Tanous if (ec) 3461abe55efSEd Tanous { 3471abe55efSEd Tanous BMCWEB_LOG_DEBUG 3481abe55efSEd Tanous << "DBUS response error " 3491abe55efSEd Tanous << ec; 350*a0803efaSEd Tanous aResp->res.result( 351*a0803efaSEd Tanous boost::beast::http::status:: 352*a0803efaSEd Tanous internal_server_error); 353c5b2abe0SLewanczyk, Dawid return; 354c5b2abe0SLewanczyk, Dawid } 3551abe55efSEd Tanous BMCWEB_LOG_DEBUG 3561abe55efSEd Tanous << "Got " << properties.size() 357c5b2abe0SLewanczyk, Dawid << "UUID properties."; 3581abe55efSEd Tanous for (const std::pair<std::string, 3591abe55efSEd Tanous VariantType> 3601abe55efSEd Tanous &p : properties) 3611abe55efSEd Tanous { 3621abe55efSEd Tanous if (p.first == "BIOSVer") 3631abe55efSEd Tanous { 364c5b2abe0SLewanczyk, Dawid const std::string *value = 3651abe55efSEd Tanous mapbox::getPtr< 3661abe55efSEd Tanous const std::string>( 3671abe55efSEd Tanous p.second); 3681abe55efSEd Tanous if (value != nullptr) 3691abe55efSEd Tanous { 3701abe55efSEd Tanous aResp->res.jsonValue 3711abe55efSEd Tanous ["BiosVersion"] = 3721abe55efSEd Tanous *value; 373c5b2abe0SLewanczyk, Dawid } 374c5b2abe0SLewanczyk, Dawid } 3751abe55efSEd Tanous if (p.first == "UUID") 3761abe55efSEd Tanous { 377c5b2abe0SLewanczyk, Dawid const std::string *value = 3781abe55efSEd Tanous mapbox::getPtr< 3791abe55efSEd Tanous const std::string>( 3801abe55efSEd Tanous p.second); 3811abe55efSEd Tanous BMCWEB_LOG_DEBUG 3821abe55efSEd Tanous << "UUID = " << *value 3831abe55efSEd Tanous << " length " 3841abe55efSEd Tanous << value->length(); 3851abe55efSEd Tanous if (value != nullptr) 3861abe55efSEd Tanous { 3871abe55efSEd Tanous // Workaround for to 3881abe55efSEd Tanous // short return str in 3891abe55efSEd Tanous // smbios demo app, 32 3901abe55efSEd Tanous // bytes are described 3911abe55efSEd Tanous // by spec 3921abe55efSEd Tanous if (value->length() > 3931abe55efSEd Tanous 0 && 3941abe55efSEd Tanous value->length() < 3951abe55efSEd Tanous 32) 3961abe55efSEd Tanous { 3971abe55efSEd Tanous std::string 3981abe55efSEd Tanous correctedValue = 3991abe55efSEd Tanous *value; 4001abe55efSEd Tanous correctedValue.append( 4011abe55efSEd Tanous 32 - 4021abe55efSEd Tanous value 4031abe55efSEd Tanous ->length(), 404c5b2abe0SLewanczyk, Dawid '0'); 4051abe55efSEd Tanous value = 4061abe55efSEd Tanous &correctedValue; 4071abe55efSEd Tanous } 4081abe55efSEd Tanous else if ( 4091abe55efSEd Tanous value->length() == 4101abe55efSEd Tanous 32) 4111abe55efSEd Tanous { 4121abe55efSEd Tanous aResp->res.jsonValue 4131abe55efSEd Tanous ["UUID"] = 4141abe55efSEd Tanous value->substr( 4151abe55efSEd Tanous 0, 8) + 4161abe55efSEd Tanous "-" + 4171abe55efSEd Tanous value->substr( 4181abe55efSEd Tanous 8, 4) + 4191abe55efSEd Tanous "-" + 4201abe55efSEd Tanous value->substr( 4211abe55efSEd Tanous 12, 4) + 4221abe55efSEd Tanous "-" + 4231abe55efSEd Tanous value->substr( 4241abe55efSEd Tanous 16, 4) + 4251abe55efSEd Tanous "-" + 4261abe55efSEd Tanous value->substr( 4271abe55efSEd Tanous 20, 12); 428c5b2abe0SLewanczyk, Dawid } 429c5b2abe0SLewanczyk, Dawid } 430c5b2abe0SLewanczyk, Dawid } 431c5b2abe0SLewanczyk, Dawid } 432c5b2abe0SLewanczyk, Dawid }, 4331abe55efSEd Tanous s.first, path, 4341abe55efSEd Tanous "org.freedesktop.DBus.Properties", 4351abe55efSEd Tanous "GetAll", 4361abe55efSEd Tanous "xyz.openbmc_project.Common.UUID"); 437c5b2abe0SLewanczyk, Dawid } 438c5b2abe0SLewanczyk, Dawid } 439c5b2abe0SLewanczyk, Dawid } 440c5b2abe0SLewanczyk, Dawid } 441c5b2abe0SLewanczyk, Dawid } 4421abe55efSEd Tanous if (foundName == false) 4431abe55efSEd Tanous { 444*a0803efaSEd Tanous aResp->res.result( 445*a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 446c5b2abe0SLewanczyk, Dawid } 447c5b2abe0SLewanczyk, Dawid }, 448c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 449c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 450c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTree", 451c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/inventory", int32_t(0), interfaces); 452c5b2abe0SLewanczyk, Dawid } 453c5b2abe0SLewanczyk, Dawid 454c5b2abe0SLewanczyk, Dawid /** 455c5b2abe0SLewanczyk, Dawid * @brief Retrieves identify led group properties over dbus 456c5b2abe0SLewanczyk, Dawid * 457c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 458c5b2abe0SLewanczyk, Dawid * @param[in] callback Callback for process retrieved data. 459c5b2abe0SLewanczyk, Dawid * 460c5b2abe0SLewanczyk, Dawid * @return None. 461c5b2abe0SLewanczyk, Dawid */ 462c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 463*a0803efaSEd Tanous void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp, 4641abe55efSEd Tanous CallbackFunc &&callback) 4651abe55efSEd Tanous { 46655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get led groups"; 46755c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 4681abe55efSEd Tanous [aResp{std::move(aResp)}, 4691abe55efSEd Tanous &callback](const boost::system::error_code &ec, 4701abe55efSEd Tanous const ManagedObjectsType &resp) { 4711abe55efSEd Tanous if (ec) 4721abe55efSEd Tanous { 47355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 474*a0803efaSEd Tanous aResp->res.result( 475*a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 476c5b2abe0SLewanczyk, Dawid return; 477c5b2abe0SLewanczyk, Dawid } 4781abe55efSEd Tanous BMCWEB_LOG_DEBUG << "Got " << resp.size() 4791abe55efSEd Tanous << "led group objects."; 4801abe55efSEd Tanous for (const auto &objPath : resp) 4811abe55efSEd Tanous { 482c5b2abe0SLewanczyk, Dawid const std::string &path = objPath.first; 4831abe55efSEd Tanous if (path.rfind("enclosure_identify") != std::string::npos) 4841abe55efSEd Tanous { 4851abe55efSEd Tanous for (const auto &interface : objPath.second) 4861abe55efSEd Tanous { 4871abe55efSEd Tanous if (interface.first == 4881abe55efSEd Tanous "xyz.openbmc_project.Led.Group") 4891abe55efSEd Tanous { 4901abe55efSEd Tanous for (const auto &property : interface.second) 4911abe55efSEd Tanous { 4921abe55efSEd Tanous if (property.first == "Asserted") 4931abe55efSEd Tanous { 494c5b2abe0SLewanczyk, Dawid const bool *asserted = 4951abe55efSEd Tanous mapbox::getPtr<const bool>( 4961abe55efSEd Tanous property.second); 4971abe55efSEd Tanous if (nullptr != asserted) 4981abe55efSEd Tanous { 499c5b2abe0SLewanczyk, Dawid callback(*asserted, aResp); 5001abe55efSEd Tanous } 5011abe55efSEd Tanous else 5021abe55efSEd Tanous { 503c5b2abe0SLewanczyk, Dawid callback(false, aResp); 504c5b2abe0SLewanczyk, Dawid } 505c5b2abe0SLewanczyk, Dawid } 506c5b2abe0SLewanczyk, Dawid } 507c5b2abe0SLewanczyk, Dawid } 508c5b2abe0SLewanczyk, Dawid } 509c5b2abe0SLewanczyk, Dawid } 510c5b2abe0SLewanczyk, Dawid } 511c5b2abe0SLewanczyk, Dawid }, 512c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.GroupManager", 5131abe55efSEd Tanous "/xyz/openbmc_project/led/groups", 5141abe55efSEd Tanous "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 515c5b2abe0SLewanczyk, Dawid } 516c5b2abe0SLewanczyk, Dawid 517c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 518*a0803efaSEd Tanous void getLedIdentify(std::shared_ptr<AsyncResp> aResp, 5191abe55efSEd Tanous CallbackFunc &&callback) 5201abe55efSEd Tanous { 52155c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get identify led properties"; 52255c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 5231abe55efSEd Tanous [aResp{std::move(aResp)}, 5241abe55efSEd Tanous &callback](const boost::system::error_code ec, 525c5b2abe0SLewanczyk, Dawid const PropertiesType &properties) { 5261abe55efSEd Tanous if (ec) 5271abe55efSEd Tanous { 52855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 529*a0803efaSEd Tanous aResp->res.result( 530*a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 531c5b2abe0SLewanczyk, Dawid return; 532c5b2abe0SLewanczyk, Dawid } 5331abe55efSEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 5341abe55efSEd Tanous << "led properties."; 535c5b2abe0SLewanczyk, Dawid std::string output; 5361abe55efSEd Tanous for (const auto &property : properties) 5371abe55efSEd Tanous { 5381abe55efSEd Tanous if (property.first == "State") 5391abe55efSEd Tanous { 540c5b2abe0SLewanczyk, Dawid const std::string *s = 54155c7b7a2SEd Tanous mapbox::getPtr<std::string>(property.second); 5421abe55efSEd Tanous if (nullptr != s) 5431abe55efSEd Tanous { 54455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Identify Led State: " << *s; 545c5b2abe0SLewanczyk, Dawid const auto pos = s->rfind('.'); 5461abe55efSEd Tanous if (pos != std::string::npos) 5471abe55efSEd Tanous { 548c5b2abe0SLewanczyk, Dawid auto led = s->substr(pos + 1); 5491abe55efSEd Tanous for (const std::pair<const char *, const char *> 5501abe55efSEd Tanous &p : 5511abe55efSEd Tanous std::array< 5521abe55efSEd Tanous std::pair<const char *, const char *>, 5531abe55efSEd Tanous 3>{{{"On", "Lit"}, 554c5b2abe0SLewanczyk, Dawid {"Blink", "Blinking"}, 5551abe55efSEd Tanous {"Off", "Off"}}}) 5561abe55efSEd Tanous { 5571abe55efSEd Tanous if (led == p.first) 5581abe55efSEd Tanous { 559c5b2abe0SLewanczyk, Dawid output = p.second; 560c5b2abe0SLewanczyk, Dawid } 561c5b2abe0SLewanczyk, Dawid } 562c5b2abe0SLewanczyk, Dawid } 563c5b2abe0SLewanczyk, Dawid } 564c5b2abe0SLewanczyk, Dawid } 565c5b2abe0SLewanczyk, Dawid } 566c5b2abe0SLewanczyk, Dawid callback(output, aResp); 567c5b2abe0SLewanczyk, Dawid }, 568c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 569c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 570c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "GetAll", 571c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical"); 572c5b2abe0SLewanczyk, Dawid } 573c5b2abe0SLewanczyk, Dawid 574c5b2abe0SLewanczyk, Dawid /** 575c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 576c5b2abe0SLewanczyk, Dawid * 577c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 578c5b2abe0SLewanczyk, Dawid * 579c5b2abe0SLewanczyk, Dawid * @return None. 580c5b2abe0SLewanczyk, Dawid */ 581*a0803efaSEd Tanous void getHostState(std::shared_ptr<AsyncResp> aResp) 5821abe55efSEd Tanous { 58355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 58455c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 585c5b2abe0SLewanczyk, Dawid [aResp{std::move(aResp)}](const boost::system::error_code ec, 586c5b2abe0SLewanczyk, Dawid const PropertiesType &properties) { 5871abe55efSEd Tanous if (ec) 5881abe55efSEd Tanous { 58955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 590*a0803efaSEd Tanous aResp->res.result( 591*a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 592c5b2abe0SLewanczyk, Dawid return; 593c5b2abe0SLewanczyk, Dawid } 5941abe55efSEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 5951abe55efSEd Tanous << "host properties."; 5961abe55efSEd Tanous for (const auto &property : properties) 5971abe55efSEd Tanous { 5981abe55efSEd Tanous if (property.first == "CurrentHostState") 5991abe55efSEd Tanous { 600c5b2abe0SLewanczyk, Dawid const std::string *s = 60155c7b7a2SEd Tanous mapbox::getPtr<const std::string>(property.second); 60255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Host state: " << *s; 6031abe55efSEd Tanous if (nullptr != s) 6041abe55efSEd Tanous { 605c5b2abe0SLewanczyk, Dawid const auto pos = s->rfind('.'); 6061abe55efSEd Tanous if (pos != std::string::npos) 6071abe55efSEd Tanous { 608c5b2abe0SLewanczyk, Dawid // Verify Host State 6091abe55efSEd Tanous if (s->substr(pos + 1) == "Running") 6101abe55efSEd Tanous { 61155c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 6121abe55efSEd Tanous aResp->res.jsonValue["Status"]["State"] = 6131abe55efSEd Tanous "Enabled"; 6141abe55efSEd Tanous } 6151abe55efSEd Tanous else 6161abe55efSEd Tanous { 61755c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 6181abe55efSEd Tanous aResp->res.jsonValue["Status"]["State"] = 6191abe55efSEd Tanous "Disabled"; 620c5b2abe0SLewanczyk, Dawid } 621c5b2abe0SLewanczyk, Dawid } 622c5b2abe0SLewanczyk, Dawid } 623c5b2abe0SLewanczyk, Dawid } 624c5b2abe0SLewanczyk, Dawid } 625c5b2abe0SLewanczyk, Dawid }, 6261abe55efSEd Tanous "xyz.openbmc_project.State.Host", 6271abe55efSEd Tanous "/xyz/openbmc_project/state/host0", 628c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "GetAll", 629c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.State.Host"); 630c5b2abe0SLewanczyk, Dawid } 631c5b2abe0SLewanczyk, Dawid }; 632c5b2abe0SLewanczyk, Dawid 633c5b2abe0SLewanczyk, Dawid /** 634c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 635c5b2abe0SLewanczyk, Dawid * Schema 636c5b2abe0SLewanczyk, Dawid */ 6371abe55efSEd Tanous class SystemsCollection : public Node 6381abe55efSEd Tanous { 639c5b2abe0SLewanczyk, Dawid public: 6401abe55efSEd Tanous SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/") 6411abe55efSEd Tanous { 642c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = 643c5b2abe0SLewanczyk, Dawid "#ComputerSystemCollection.ComputerSystemCollection"; 644c5b2abe0SLewanczyk, Dawid Node::json["@odata.id"] = "/redfish/v1/Systems"; 645c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 646c5b2abe0SLewanczyk, Dawid "/redfish/v1/" 647c5b2abe0SLewanczyk, Dawid "$metadata#ComputerSystemCollection.ComputerSystemCollection"; 648c5b2abe0SLewanczyk, Dawid Node::json["Name"] = "Computer System Collection"; 649c5b2abe0SLewanczyk, Dawid 650c5b2abe0SLewanczyk, Dawid entityPrivileges = { 651c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 652c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 653c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 654c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 655c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 656c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 657c5b2abe0SLewanczyk, Dawid } 658c5b2abe0SLewanczyk, Dawid 659c5b2abe0SLewanczyk, Dawid private: 660c5b2abe0SLewanczyk, Dawid /** 661c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 662c5b2abe0SLewanczyk, Dawid */ 66355c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 6641abe55efSEd Tanous const std::vector<std::string> ¶ms) override 6651abe55efSEd Tanous { 666c5b2abe0SLewanczyk, Dawid // Get board list, and call the below callback for JSON preparation 6671abe55efSEd Tanous provider.getBaseboardList([&](const bool &success, 6681abe55efSEd Tanous const std::vector<std::string> &output) { 6691abe55efSEd Tanous if (success) 6701abe55efSEd Tanous { 671c5b2abe0SLewanczyk, Dawid // ... prepare json array with appropriate @odata.id links 672c5b2abe0SLewanczyk, Dawid nlohmann::json boardArray = nlohmann::json::array(); 6731abe55efSEd Tanous for (const std::string &boardItem : output) 6741abe55efSEd Tanous { 675c5b2abe0SLewanczyk, Dawid boardArray.push_back( 676d76323e5SEd Tanous {{"@odata.id", "/redfish/v1/Systems/" + boardItem}}); 677c5b2abe0SLewanczyk, Dawid } 678c5b2abe0SLewanczyk, Dawid // Then attach members, count size and return, 679c5b2abe0SLewanczyk, Dawid Node::json["Members"] = boardArray; 680c5b2abe0SLewanczyk, Dawid Node::json["Members@odata.count"] = boardArray.size(); 68155c7b7a2SEd Tanous res.jsonValue = Node::json; 6821abe55efSEd Tanous } 6831abe55efSEd Tanous else 6841abe55efSEd Tanous { 685c5b2abe0SLewanczyk, Dawid // ... otherwise, return INTERNALL ERROR 686c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 687c5b2abe0SLewanczyk, Dawid } 688c5b2abe0SLewanczyk, Dawid res.end(); 689c5b2abe0SLewanczyk, Dawid }); 690c5b2abe0SLewanczyk, Dawid } 691c5b2abe0SLewanczyk, Dawid 692c5b2abe0SLewanczyk, Dawid OnDemandSystemsProvider provider; 693c5b2abe0SLewanczyk, Dawid }; 694c5b2abe0SLewanczyk, Dawid 695c5b2abe0SLewanczyk, Dawid /** 696c5b2abe0SLewanczyk, Dawid * Systems override class for delivering ComputerSystems Schema 697c5b2abe0SLewanczyk, Dawid */ 6981abe55efSEd Tanous class Systems : public Node 6991abe55efSEd Tanous { 700c5b2abe0SLewanczyk, Dawid public: 701c5b2abe0SLewanczyk, Dawid /* 702c5b2abe0SLewanczyk, Dawid * Default Constructor 703c5b2abe0SLewanczyk, Dawid */ 7041abe55efSEd Tanous Systems(CrowApp &app) : 7051abe55efSEd Tanous Node(app, "/redfish/v1/Systems/<str>/", std::string()) 7061abe55efSEd Tanous { 707c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem"; 708c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 709c5b2abe0SLewanczyk, Dawid "/redfish/v1/$metadata#ComputerSystem.ComputerSystem"; 710c5b2abe0SLewanczyk, Dawid Node::json["SystemType"] = "Physical"; 711c5b2abe0SLewanczyk, Dawid Node::json["Description"] = "Computer System"; 712c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideEnabled"] = 713c5b2abe0SLewanczyk, Dawid "Disabled"; // TODO(Dawid), get real boot data 714c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideTarget"] = 715c5b2abe0SLewanczyk, Dawid "None"; // TODO(Dawid), get real boot data 716c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideMode"] = 717c5b2abe0SLewanczyk, Dawid "Legacy"; // TODO(Dawid), get real boot data 7181abe55efSEd Tanous Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] = 7191abe55efSEd Tanous {"None", "Pxe", "Hdd", "Cd", 7201abe55efSEd Tanous "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot 7211abe55efSEd Tanous // data 722c5b2abe0SLewanczyk, Dawid Node::json["ProcessorSummary"]["Count"] = int(0); 723c5b2abe0SLewanczyk, Dawid Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled"; 724c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0); 725c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["Status"]["State"] = "Disabled"; 726c5b2abe0SLewanczyk, Dawid 727c5b2abe0SLewanczyk, Dawid entityPrivileges = { 728c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 729c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 730c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 731c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 732c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 733c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 734c5b2abe0SLewanczyk, Dawid } 735c5b2abe0SLewanczyk, Dawid 736c5b2abe0SLewanczyk, Dawid private: 737c5b2abe0SLewanczyk, Dawid OnDemandSystemsProvider provider; 738c5b2abe0SLewanczyk, Dawid 739c5b2abe0SLewanczyk, Dawid /** 740c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 741c5b2abe0SLewanczyk, Dawid */ 74255c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 7431abe55efSEd Tanous const std::vector<std::string> ¶ms) override 7441abe55efSEd Tanous { 745c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 746c5b2abe0SLewanczyk, Dawid // impossible 7471abe55efSEd Tanous if (params.size() != 1) 7481abe55efSEd Tanous { 749c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 750c5b2abe0SLewanczyk, Dawid res.end(); 751c5b2abe0SLewanczyk, Dawid return; 752c5b2abe0SLewanczyk, Dawid } 753c5b2abe0SLewanczyk, Dawid 754c5b2abe0SLewanczyk, Dawid const std::string &name = params[0]; 755c5b2abe0SLewanczyk, Dawid 75655c7b7a2SEd Tanous res.jsonValue = Node::json; 75755c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 758c5b2abe0SLewanczyk, Dawid 759*a0803efaSEd Tanous auto asyncResp = std::make_shared<AsyncResp>(res); 760c5b2abe0SLewanczyk, Dawid 761c5b2abe0SLewanczyk, Dawid provider.getLedGroupIdentify( 762*a0803efaSEd Tanous asyncResp, 763*a0803efaSEd Tanous [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) { 7641abe55efSEd Tanous if (asserted) 7651abe55efSEd Tanous { 766c5b2abe0SLewanczyk, Dawid // If led group is asserted, then another call is needed to 767c5b2abe0SLewanczyk, Dawid // get led status 768c5b2abe0SLewanczyk, Dawid provider.getLedIdentify( 769*a0803efaSEd Tanous aResp, [](const std::string &ledStatus, 770*a0803efaSEd Tanous const std::shared_ptr<AsyncResp> &aResp) { 7711abe55efSEd Tanous if (!ledStatus.empty()) 7721abe55efSEd Tanous { 7731abe55efSEd Tanous aResp->res.jsonValue["IndicatorLED"] = 7741abe55efSEd Tanous ledStatus; 775c5b2abe0SLewanczyk, Dawid } 776c5b2abe0SLewanczyk, Dawid }); 7771abe55efSEd Tanous } 7781abe55efSEd Tanous else 7791abe55efSEd Tanous { 78055c7b7a2SEd Tanous aResp->res.jsonValue["IndicatorLED"] = "Off"; 781c5b2abe0SLewanczyk, Dawid } 782c5b2abe0SLewanczyk, Dawid }); 783c5b2abe0SLewanczyk, Dawid provider.getComputerSystem(asyncResp, name); 784c5b2abe0SLewanczyk, Dawid provider.getHostState(asyncResp); 785c5b2abe0SLewanczyk, Dawid } 786c5b2abe0SLewanczyk, Dawid 78755c7b7a2SEd Tanous void doPatch(crow::Response &res, const crow::Request &req, 7881abe55efSEd Tanous const std::vector<std::string> ¶ms) override 7891abe55efSEd Tanous { 790c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 791c5b2abe0SLewanczyk, Dawid // impossible 7921abe55efSEd Tanous if (params.size() != 1) 7931abe55efSEd Tanous { 794c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 795c5b2abe0SLewanczyk, Dawid res.end(); 796c5b2abe0SLewanczyk, Dawid return; 797c5b2abe0SLewanczyk, Dawid } 798c5b2abe0SLewanczyk, Dawid // Parse JSON request body 799c5b2abe0SLewanczyk, Dawid nlohmann::json patch; 8001abe55efSEd Tanous if (!json_util::processJsonFromRequest(res, req, patch)) 8011abe55efSEd Tanous { 802c5b2abe0SLewanczyk, Dawid return; 803c5b2abe0SLewanczyk, Dawid } 804c5b2abe0SLewanczyk, Dawid // Find key with new led value 805c5b2abe0SLewanczyk, Dawid const std::string &name = params[0]; 806c5b2abe0SLewanczyk, Dawid const std::string *reqLedState = nullptr; 807c5b2abe0SLewanczyk, Dawid json_util::Result r = json_util::getString( 808c5b2abe0SLewanczyk, Dawid "IndicatorLED", patch, reqLedState, 809c5b2abe0SLewanczyk, Dawid static_cast<int>(json_util::MessageSetting::TYPE_ERROR) | 810c5b2abe0SLewanczyk, Dawid static_cast<int>(json_util::MessageSetting::MISSING), 81155c7b7a2SEd Tanous res.jsonValue, std::string("/" + name + "/IndicatorLED")); 8121abe55efSEd Tanous if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr)) 8131abe55efSEd Tanous { 814c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::bad_request); 815c5b2abe0SLewanczyk, Dawid res.end(); 816c5b2abe0SLewanczyk, Dawid return; 817c5b2abe0SLewanczyk, Dawid } 818c5b2abe0SLewanczyk, Dawid // Verify key value 819c5b2abe0SLewanczyk, Dawid std::string dbusLedState; 8201abe55efSEd Tanous for (const auto &p : 8211abe55efSEd Tanous boost::container::flat_map<const char *, const char *>{ 8221abe55efSEd Tanous {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}}) 8231abe55efSEd Tanous { 8241abe55efSEd Tanous if (*reqLedState == p.second) 8251abe55efSEd Tanous { 826c5b2abe0SLewanczyk, Dawid dbusLedState = p.first; 827c5b2abe0SLewanczyk, Dawid } 828c5b2abe0SLewanczyk, Dawid } 829c5b2abe0SLewanczyk, Dawid 830c5b2abe0SLewanczyk, Dawid // Update led status 831*a0803efaSEd Tanous auto asyncResp = std::make_shared<AsyncResp>(res); 83255c7b7a2SEd Tanous res.jsonValue = Node::json; 83355c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 834c5b2abe0SLewanczyk, Dawid 835c5b2abe0SLewanczyk, Dawid provider.getHostState(asyncResp); 836c5b2abe0SLewanczyk, Dawid provider.getComputerSystem(asyncResp, name); 837c5b2abe0SLewanczyk, Dawid 8381abe55efSEd Tanous if (dbusLedState.empty()) 8391abe55efSEd Tanous { 840c5b2abe0SLewanczyk, Dawid messages::addMessageToJsonRoot( 84155c7b7a2SEd Tanous res.jsonValue, 842c5b2abe0SLewanczyk, Dawid messages::propertyValueNotInList(*reqLedState, "IndicatorLED")); 8431abe55efSEd Tanous } 8441abe55efSEd Tanous else 8451abe55efSEd Tanous { 846c5b2abe0SLewanczyk, Dawid // Update led group 84755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led group."; 84855c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 849c5b2abe0SLewanczyk, Dawid [&, asyncResp{std::move(asyncResp)}]( 850c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 8511abe55efSEd Tanous if (ec) 8521abe55efSEd Tanous { 85355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 854*a0803efaSEd Tanous asyncResp->res.result( 855*a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 856c5b2abe0SLewanczyk, Dawid return; 857c5b2abe0SLewanczyk, Dawid } 85855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led group update done."; 859c5b2abe0SLewanczyk, Dawid }, 860c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.GroupManager", 861c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/groups/enclosure_identify", 862c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 863c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Group", "Asserted", 864c5b2abe0SLewanczyk, Dawid sdbusplus::message::variant<bool>( 865c5b2abe0SLewanczyk, Dawid (dbusLedState == "Off" ? false : true))); 866c5b2abe0SLewanczyk, Dawid // Update identify led status 86755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection."; 86855c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 869c5b2abe0SLewanczyk, Dawid [&, asyncResp{std::move(asyncResp)}]( 870c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 8711abe55efSEd Tanous if (ec) 8721abe55efSEd Tanous { 87355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 874*a0803efaSEd Tanous asyncResp->res.result( 875*a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 876c5b2abe0SLewanczyk, Dawid return; 877c5b2abe0SLewanczyk, Dawid } 87855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led state update done."; 87955c7b7a2SEd Tanous res.jsonValue["IndicatorLED"] = *reqLedState; 880c5b2abe0SLewanczyk, Dawid }, 881c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 882c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 883c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 884c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical", "State", 885c5b2abe0SLewanczyk, Dawid sdbusplus::message::variant<std::string>( 886c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical.Action." + dbusLedState)); 887c5b2abe0SLewanczyk, Dawid } 888c5b2abe0SLewanczyk, Dawid } 889c5b2abe0SLewanczyk, Dawid }; 890c5b2abe0SLewanczyk, Dawid } // namespace redfish 891