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 <utils/json_utils.hpp> 22c5b2abe0SLewanczyk, Dawid 231abe55efSEd Tanous namespace redfish 241abe55efSEd Tanous { 25c5b2abe0SLewanczyk, Dawid 26c5b2abe0SLewanczyk, Dawid /** 27c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 28c5b2abe0SLewanczyk, Dawid * 29c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls 30c5b2abe0SLewanczyk, Dawid * @param[in] name Computer system name from request 31c5b2abe0SLewanczyk, Dawid * 32c5b2abe0SLewanczyk, Dawid * @return None. 33c5b2abe0SLewanczyk, Dawid */ 34a0803efaSEd Tanous void getComputerSystem(std::shared_ptr<AsyncResp> aResp, 351abe55efSEd Tanous const std::string &name) 361abe55efSEd Tanous { 3755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 3855c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 39c5b2abe0SLewanczyk, Dawid [name, aResp{std::move(aResp)}]( 40c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 41c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 426c34de48SEd Tanous std::string, 436c34de48SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>> 44c5b2abe0SLewanczyk, Dawid &subtree) { 451abe55efSEd Tanous if (ec) 461abe55efSEd Tanous { 4755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 48a0803efaSEd Tanous aResp->res.result( 49a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 50c5b2abe0SLewanczyk, Dawid return; 51c5b2abe0SLewanczyk, Dawid } 52c5b2abe0SLewanczyk, Dawid bool foundName = false; 53c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 546c34de48SEd Tanous for (const std::pair<std::string, 556c34de48SEd Tanous std::vector<std::pair< 566c34de48SEd Tanous std::string, std::vector<std::string>>>> 571abe55efSEd Tanous &object : subtree) 581abe55efSEd Tanous { 59c5b2abe0SLewanczyk, Dawid const std::string &path = object.first; 6055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 611abe55efSEd Tanous const std::vector< 621abe55efSEd Tanous std::pair<std::string, std::vector<std::string>>> 63c5b2abe0SLewanczyk, Dawid &connectionNames = object.second; 641abe55efSEd Tanous if (connectionNames.size() < 1) 651abe55efSEd Tanous { 66c5b2abe0SLewanczyk, Dawid continue; 67c5b2abe0SLewanczyk, Dawid } 68c5b2abe0SLewanczyk, Dawid // Check if computer system exist 691abe55efSEd Tanous if (boost::ends_with(path, name)) 701abe55efSEd Tanous { 71c5b2abe0SLewanczyk, Dawid foundName = true; 7255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Found name: " << name; 736c34de48SEd Tanous const std::string connectionName = connectionNames[0].first; 7455c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 75c5b2abe0SLewanczyk, Dawid [aResp, name(std::string(name))]( 76c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 776c34de48SEd Tanous const std::vector<std::pair< 786c34de48SEd Tanous std::string, VariantType>> &propertiesList) { 791abe55efSEd Tanous if (ec) 801abe55efSEd Tanous { 811abe55efSEd Tanous BMCWEB_LOG_ERROR << "DBUS response error: " 821abe55efSEd Tanous << ec; 836c34de48SEd Tanous aResp->res.result(boost::beast::http::status:: 84a0803efaSEd Tanous internal_server_error); 85c5b2abe0SLewanczyk, Dawid return; 86c5b2abe0SLewanczyk, Dawid } 876c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " << propertiesList.size() 88c5b2abe0SLewanczyk, Dawid << "properties for system"; 891abe55efSEd Tanous for (const std::pair<std::string, VariantType> 901abe55efSEd Tanous &property : propertiesList) 911abe55efSEd Tanous { 92c5b2abe0SLewanczyk, Dawid const std::string *value = 931abe55efSEd Tanous mapbox::getPtr<const std::string>( 941abe55efSEd Tanous property.second); 951abe55efSEd Tanous if (value != nullptr) 961abe55efSEd Tanous { 971abe55efSEd Tanous aResp->res.jsonValue[property.first] = 981abe55efSEd Tanous *value; 99c5b2abe0SLewanczyk, Dawid } 100c5b2abe0SLewanczyk, Dawid } 10155c7b7a2SEd Tanous aResp->res.jsonValue["Name"] = name; 10255c7b7a2SEd Tanous aResp->res.jsonValue["Id"] = 10355c7b7a2SEd Tanous aResp->res.jsonValue["SerialNumber"]; 104c5b2abe0SLewanczyk, Dawid }, 1056c34de48SEd Tanous connectionName, path, "org.freedesktop.DBus.Properties", 1066c34de48SEd Tanous "GetAll", 1071abe55efSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset"); 1081abe55efSEd Tanous } 1091abe55efSEd Tanous else 1101abe55efSEd Tanous { 1116c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 1126c34de48SEd Tanous // BiosVer 113*04a258f4SEd Tanous for (const auto &connection : connectionNames) 1141abe55efSEd Tanous { 115*04a258f4SEd Tanous for (const auto &interfaceName : connection.second) 1161abe55efSEd Tanous { 117*04a258f4SEd Tanous if (interfaceName == 118*04a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 1191abe55efSEd Tanous { 1201abe55efSEd Tanous BMCWEB_LOG_DEBUG 121*04a258f4SEd Tanous << "Found Dimm, now get its properties."; 12255c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 1236617338dSEd Tanous [aResp]( 1241abe55efSEd Tanous const boost::system::error_code ec, 1256c34de48SEd Tanous const std::vector< 1266c34de48SEd Tanous std::pair<std::string, VariantType>> 1271abe55efSEd Tanous &properties) { 1281abe55efSEd Tanous if (ec) 1291abe55efSEd Tanous { 1301abe55efSEd Tanous BMCWEB_LOG_ERROR 1316c34de48SEd Tanous << "DBUS response error " << ec; 132a0803efaSEd Tanous aResp->res.result( 133a0803efaSEd Tanous boost::beast::http::status:: 134a0803efaSEd Tanous internal_server_error); 135c5b2abe0SLewanczyk, Dawid return; 136c5b2abe0SLewanczyk, Dawid } 1376c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " 1386c34de48SEd Tanous << properties.size() 139c5b2abe0SLewanczyk, Dawid << "Dimm properties."; 140*04a258f4SEd Tanous for (const std::pair<std::string, 141*04a258f4SEd Tanous VariantType> 142*04a258f4SEd Tanous &property : properties) 1431abe55efSEd Tanous { 144*04a258f4SEd Tanous if (property.first == 145*04a258f4SEd Tanous "MemorySizeInKb") 1461abe55efSEd Tanous { 147*04a258f4SEd Tanous const uint64_t *value = 1481abe55efSEd Tanous mapbox::getPtr< 149*04a258f4SEd Tanous const uint64_t>( 150*04a258f4SEd Tanous property.second); 151*04a258f4SEd Tanous if (value != nullptr) 1521abe55efSEd Tanous { 1531abe55efSEd Tanous aResp->res.jsonValue 1546c34de48SEd Tanous ["TotalSystemMemoryGi" 1556c34de48SEd Tanous "B"] += 156*04a258f4SEd Tanous *value / (1024 * 1024); 1571abe55efSEd Tanous aResp->res.jsonValue 1581abe55efSEd Tanous ["MemorySummary"] 1596c34de48SEd Tanous ["Status"]["State"] = 1601abe55efSEd Tanous "Enabled"; 161c5b2abe0SLewanczyk, Dawid } 162c5b2abe0SLewanczyk, Dawid } 163c5b2abe0SLewanczyk, Dawid } 164c5b2abe0SLewanczyk, Dawid }, 165*04a258f4SEd Tanous connection.first, path, 1666c34de48SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 1676c34de48SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm"); 1681abe55efSEd Tanous } 169*04a258f4SEd Tanous else if (interfaceName == 170*04a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 1711abe55efSEd Tanous { 1721abe55efSEd Tanous BMCWEB_LOG_DEBUG 173*04a258f4SEd Tanous << "Found Cpu, now get its properties."; 174a0803efaSEd Tanous crow::connections::systemBus->async_method_call( 1756617338dSEd Tanous [aResp]( 176a0803efaSEd Tanous const boost::system::error_code ec, 1776c34de48SEd Tanous const std::vector< 1786c34de48SEd Tanous std::pair<std::string, VariantType>> 1791abe55efSEd Tanous &properties) { 1801abe55efSEd Tanous if (ec) 1811abe55efSEd Tanous { 1821abe55efSEd Tanous BMCWEB_LOG_ERROR 1836c34de48SEd Tanous << "DBUS response error " << ec; 184a0803efaSEd Tanous aResp->res.result( 185a0803efaSEd Tanous boost::beast::http::status:: 186a0803efaSEd Tanous internal_server_error); 187c5b2abe0SLewanczyk, Dawid return; 188c5b2abe0SLewanczyk, Dawid } 1896c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " 1906c34de48SEd Tanous << properties.size() 191c5b2abe0SLewanczyk, Dawid << "Cpu properties."; 192*04a258f4SEd Tanous for (const auto &property : properties) 1931abe55efSEd Tanous { 194*04a258f4SEd Tanous if (property.first == 195*04a258f4SEd Tanous "ProcessorFamily") 1961abe55efSEd Tanous { 197a0803efaSEd Tanous const std::string *value = 1981abe55efSEd Tanous mapbox::getPtr< 199a0803efaSEd Tanous const std::string>( 200*04a258f4SEd Tanous property.second); 2011abe55efSEd Tanous if (value != nullptr) 2021abe55efSEd Tanous { 203*04a258f4SEd Tanous nlohmann::json 204*04a258f4SEd Tanous &procSummary = 2051abe55efSEd Tanous aResp->res.jsonValue 2066c34de48SEd Tanous ["ProcessorSumm" 207*04a258f4SEd Tanous "ary"]; 208*04a258f4SEd Tanous nlohmann::json &procCount = 209*04a258f4SEd Tanous procSummary["Count"]; 210*04a258f4SEd Tanous 211*04a258f4SEd Tanous procCount = 212*04a258f4SEd Tanous procCount.get<int>() + 213c5b2abe0SLewanczyk, Dawid 1; 214*04a258f4SEd Tanous procSummary["Status"] 215*04a258f4SEd Tanous ["State"] = 216c5b2abe0SLewanczyk, Dawid "Enabled"; 217*04a258f4SEd Tanous procSummary["Model"] = 218*04a258f4SEd Tanous *value; 219c5b2abe0SLewanczyk, Dawid } 220c5b2abe0SLewanczyk, Dawid } 221c5b2abe0SLewanczyk, Dawid } 222c5b2abe0SLewanczyk, Dawid }, 223*04a258f4SEd Tanous connection.first, path, 2246c34de48SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 2256c34de48SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu"); 2261abe55efSEd Tanous } 227*04a258f4SEd Tanous else if (interfaceName == 228*04a258f4SEd Tanous "xyz.openbmc_project.Common.UUID") 2291abe55efSEd Tanous { 2301abe55efSEd Tanous BMCWEB_LOG_DEBUG 231*04a258f4SEd Tanous << "Found UUID, now get its properties."; 23255c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 2331abe55efSEd Tanous [aResp]( 2341abe55efSEd Tanous const boost::system::error_code ec, 2356c34de48SEd Tanous const std::vector< 2366c34de48SEd Tanous std::pair<std::string, VariantType>> 2371abe55efSEd Tanous &properties) { 2381abe55efSEd Tanous if (ec) 2391abe55efSEd Tanous { 2401abe55efSEd Tanous BMCWEB_LOG_DEBUG 2416c34de48SEd Tanous << "DBUS response error " << ec; 242a0803efaSEd Tanous aResp->res.result( 243a0803efaSEd Tanous boost::beast::http::status:: 244a0803efaSEd Tanous internal_server_error); 245c5b2abe0SLewanczyk, Dawid return; 246c5b2abe0SLewanczyk, Dawid } 2476c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " 2486c34de48SEd Tanous << properties.size() 249c5b2abe0SLewanczyk, Dawid << "UUID properties."; 2501abe55efSEd Tanous for (const std::pair<std::string, 251*04a258f4SEd Tanous VariantType> 252*04a258f4SEd Tanous &property : properties) 2531abe55efSEd Tanous { 254*04a258f4SEd Tanous if (property.first == "BIOSVer") 2551abe55efSEd Tanous { 256c5b2abe0SLewanczyk, Dawid const std::string *value = 2571abe55efSEd Tanous mapbox::getPtr< 2581abe55efSEd Tanous const std::string>( 259*04a258f4SEd Tanous property.second); 2601abe55efSEd Tanous if (value != nullptr) 2611abe55efSEd Tanous { 2621abe55efSEd Tanous aResp->res.jsonValue 2631abe55efSEd Tanous ["BiosVersion"] = 2641abe55efSEd Tanous *value; 265c5b2abe0SLewanczyk, Dawid } 266c5b2abe0SLewanczyk, Dawid } 267*04a258f4SEd Tanous if (property.first == "UUID") 2681abe55efSEd Tanous { 269c5b2abe0SLewanczyk, Dawid const std::string *value = 2701abe55efSEd Tanous mapbox::getPtr< 2711abe55efSEd Tanous const std::string>( 272*04a258f4SEd Tanous property.second); 273*04a258f4SEd Tanous 2741abe55efSEd Tanous if (value != nullptr) 2751abe55efSEd Tanous { 276*04a258f4SEd Tanous std::string valueStr = 2771abe55efSEd Tanous *value; 278*04a258f4SEd Tanous if (valueStr.size() == 32) 2791abe55efSEd Tanous { 280*04a258f4SEd Tanous valueStr.insert(8, 1, 281*04a258f4SEd Tanous '-'); 282*04a258f4SEd Tanous valueStr.insert(13, 1, 283*04a258f4SEd Tanous '-'); 284*04a258f4SEd Tanous valueStr.insert(18, 1, 285*04a258f4SEd Tanous '-'); 286*04a258f4SEd Tanous valueStr.insert(23, 1, 287*04a258f4SEd Tanous '-'); 288*04a258f4SEd Tanous } 289*04a258f4SEd Tanous BMCWEB_LOG_DEBUG 290*04a258f4SEd Tanous << "UUID = " 291*04a258f4SEd Tanous << valueStr; 2926c34de48SEd Tanous aResp->res 2936c34de48SEd Tanous .jsonValue["UUID"] = 294*04a258f4SEd Tanous valueStr; 295c5b2abe0SLewanczyk, Dawid } 296c5b2abe0SLewanczyk, Dawid } 297c5b2abe0SLewanczyk, Dawid } 298c5b2abe0SLewanczyk, Dawid }, 299*04a258f4SEd Tanous connection.first, path, 3006c34de48SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 3011abe55efSEd Tanous "xyz.openbmc_project.Common.UUID"); 302c5b2abe0SLewanczyk, Dawid } 303c5b2abe0SLewanczyk, Dawid } 304c5b2abe0SLewanczyk, Dawid } 305c5b2abe0SLewanczyk, Dawid } 306c5b2abe0SLewanczyk, Dawid } 3071abe55efSEd Tanous if (foundName == false) 3081abe55efSEd Tanous { 309a0803efaSEd Tanous aResp->res.result( 310a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 311c5b2abe0SLewanczyk, Dawid } 312c5b2abe0SLewanczyk, Dawid }, 313c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 314c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 315c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTree", 3166617338dSEd Tanous "/xyz/openbmc_project/inventory", int32_t(0), 3176617338dSEd Tanous std::array<const char *, 5>{ 3186617338dSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset", 3196617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu", 3206617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm", 3216617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.System", 3226617338dSEd Tanous "xyz.openbmc_project.Common.UUID", 3236617338dSEd Tanous }); 324c5b2abe0SLewanczyk, Dawid } 325c5b2abe0SLewanczyk, Dawid 326c5b2abe0SLewanczyk, Dawid /** 327c5b2abe0SLewanczyk, Dawid * @brief Retrieves identify led group properties over dbus 328c5b2abe0SLewanczyk, Dawid * 329c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 330c5b2abe0SLewanczyk, Dawid * @param[in] callback Callback for process retrieved data. 331c5b2abe0SLewanczyk, Dawid * 332c5b2abe0SLewanczyk, Dawid * @return None. 333c5b2abe0SLewanczyk, Dawid */ 334c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 335a0803efaSEd Tanous void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp, 3361abe55efSEd Tanous CallbackFunc &&callback) 3371abe55efSEd Tanous { 33855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get led groups"; 33955c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 3401abe55efSEd Tanous [aResp{std::move(aResp)}, 3416617338dSEd Tanous callback{std::move(callback)}](const boost::system::error_code &ec, 3421abe55efSEd Tanous const ManagedObjectsType &resp) { 3431abe55efSEd Tanous if (ec) 3441abe55efSEd Tanous { 34555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 346a0803efaSEd Tanous aResp->res.result( 347a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 348c5b2abe0SLewanczyk, Dawid return; 349c5b2abe0SLewanczyk, Dawid } 3506c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects."; 3511abe55efSEd Tanous for (const auto &objPath : resp) 3521abe55efSEd Tanous { 353c5b2abe0SLewanczyk, Dawid const std::string &path = objPath.first; 3541abe55efSEd Tanous if (path.rfind("enclosure_identify") != std::string::npos) 3551abe55efSEd Tanous { 3561abe55efSEd Tanous for (const auto &interface : objPath.second) 3571abe55efSEd Tanous { 3586c34de48SEd Tanous if (interface.first == "xyz.openbmc_project.Led.Group") 3591abe55efSEd Tanous { 3601abe55efSEd Tanous for (const auto &property : interface.second) 3611abe55efSEd Tanous { 3621abe55efSEd Tanous if (property.first == "Asserted") 3631abe55efSEd Tanous { 364c5b2abe0SLewanczyk, Dawid const bool *asserted = 3651abe55efSEd Tanous mapbox::getPtr<const bool>( 3661abe55efSEd Tanous property.second); 3671abe55efSEd Tanous if (nullptr != asserted) 3681abe55efSEd Tanous { 369c5b2abe0SLewanczyk, Dawid callback(*asserted, aResp); 3701abe55efSEd Tanous } 3711abe55efSEd Tanous else 3721abe55efSEd Tanous { 373c5b2abe0SLewanczyk, Dawid callback(false, aResp); 374c5b2abe0SLewanczyk, Dawid } 375c5b2abe0SLewanczyk, Dawid } 376c5b2abe0SLewanczyk, Dawid } 377c5b2abe0SLewanczyk, Dawid } 378c5b2abe0SLewanczyk, Dawid } 379c5b2abe0SLewanczyk, Dawid } 380c5b2abe0SLewanczyk, Dawid } 381c5b2abe0SLewanczyk, Dawid }, 382c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.GroupManager", 3836c34de48SEd Tanous "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager", 3846c34de48SEd Tanous "GetManagedObjects"); 385c5b2abe0SLewanczyk, Dawid } 386c5b2abe0SLewanczyk, Dawid 387c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 3886c34de48SEd Tanous void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback) 3891abe55efSEd Tanous { 39055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get identify led properties"; 39155c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 3926617338dSEd Tanous [aResp, 3936617338dSEd Tanous callback{std::move(callback)}](const boost::system::error_code ec, 394c5b2abe0SLewanczyk, Dawid const PropertiesType &properties) { 3951abe55efSEd Tanous if (ec) 3961abe55efSEd Tanous { 39755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 398a0803efaSEd Tanous aResp->res.result( 399a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 400c5b2abe0SLewanczyk, Dawid return; 401c5b2abe0SLewanczyk, Dawid } 4021abe55efSEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 4031abe55efSEd Tanous << "led properties."; 404c5b2abe0SLewanczyk, Dawid std::string output; 4051abe55efSEd Tanous for (const auto &property : properties) 4061abe55efSEd Tanous { 4071abe55efSEd Tanous if (property.first == "State") 4081abe55efSEd Tanous { 409c5b2abe0SLewanczyk, Dawid const std::string *s = 41055c7b7a2SEd Tanous mapbox::getPtr<std::string>(property.second); 4111abe55efSEd Tanous if (nullptr != s) 4121abe55efSEd Tanous { 41355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Identify Led State: " << *s; 414c5b2abe0SLewanczyk, Dawid const auto pos = s->rfind('.'); 4151abe55efSEd Tanous if (pos != std::string::npos) 4161abe55efSEd Tanous { 417c5b2abe0SLewanczyk, Dawid auto led = s->substr(pos + 1); 4181abe55efSEd Tanous for (const std::pair<const char *, const char *> 4191abe55efSEd Tanous &p : 4201abe55efSEd Tanous std::array< 4216c34de48SEd Tanous std::pair<const char *, const char *>, 3>{ 4226c34de48SEd Tanous {{"On", "Lit"}, 423c5b2abe0SLewanczyk, Dawid {"Blink", "Blinking"}, 4241abe55efSEd Tanous {"Off", "Off"}}}) 4251abe55efSEd Tanous { 4261abe55efSEd Tanous if (led == p.first) 4271abe55efSEd Tanous { 428c5b2abe0SLewanczyk, Dawid output = p.second; 429c5b2abe0SLewanczyk, Dawid } 430c5b2abe0SLewanczyk, Dawid } 431c5b2abe0SLewanczyk, Dawid } 432c5b2abe0SLewanczyk, Dawid } 433c5b2abe0SLewanczyk, Dawid } 434c5b2abe0SLewanczyk, Dawid } 435c5b2abe0SLewanczyk, Dawid callback(output, aResp); 436c5b2abe0SLewanczyk, Dawid }, 437c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 438c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 439c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "GetAll", 440c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical"); 441c5b2abe0SLewanczyk, Dawid } 442c5b2abe0SLewanczyk, Dawid 443c5b2abe0SLewanczyk, Dawid /** 444c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 445c5b2abe0SLewanczyk, Dawid * 446c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 447c5b2abe0SLewanczyk, Dawid * 448c5b2abe0SLewanczyk, Dawid * @return None. 449c5b2abe0SLewanczyk, Dawid */ 450a0803efaSEd Tanous void getHostState(std::shared_ptr<AsyncResp> aResp) 4511abe55efSEd Tanous { 45255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 45355c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 4546617338dSEd Tanous [aResp{std::move(aResp)}]( 4556617338dSEd Tanous const boost::system::error_code ec, 4566617338dSEd Tanous const sdbusplus::message::variant<std::string> &hostState) { 4571abe55efSEd Tanous if (ec) 4581abe55efSEd Tanous { 45955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 460a0803efaSEd Tanous aResp->res.result( 461a0803efaSEd Tanous boost::beast::http::status::internal_server_error); 462c5b2abe0SLewanczyk, Dawid return; 463c5b2abe0SLewanczyk, Dawid } 4646617338dSEd Tanous 4656617338dSEd Tanous const std::string *s = mapbox::getPtr<const std::string>(hostState); 46655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Host state: " << *s; 4676617338dSEd Tanous if (s != nullptr) 4681abe55efSEd Tanous { 469c5b2abe0SLewanczyk, Dawid // Verify Host State 4706617338dSEd Tanous if (*s == "xyz.openbmc_project.State.Host.Running") 4711abe55efSEd Tanous { 47255c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 4736617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Enabled"; 4741abe55efSEd Tanous } 4751abe55efSEd Tanous else 4761abe55efSEd Tanous { 47755c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 4786617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Disabled"; 479c5b2abe0SLewanczyk, Dawid } 480c5b2abe0SLewanczyk, Dawid } 481c5b2abe0SLewanczyk, Dawid }, 4826c34de48SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 4836617338dSEd Tanous "org.freedesktop.DBus.Properties", "Get", 4846617338dSEd Tanous "xyz.openbmc_project.State.Host", "CurrentHostState"); 485c5b2abe0SLewanczyk, Dawid } 486c5b2abe0SLewanczyk, Dawid 487c5b2abe0SLewanczyk, Dawid /** 488c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 489c5b2abe0SLewanczyk, Dawid * Schema 490c5b2abe0SLewanczyk, Dawid */ 4911abe55efSEd Tanous class SystemsCollection : public Node 4921abe55efSEd Tanous { 493c5b2abe0SLewanczyk, Dawid public: 4941abe55efSEd Tanous SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/") 4951abe55efSEd Tanous { 496c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = 497c5b2abe0SLewanczyk, Dawid "#ComputerSystemCollection.ComputerSystemCollection"; 498c5b2abe0SLewanczyk, Dawid Node::json["@odata.id"] = "/redfish/v1/Systems"; 499c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 500c5b2abe0SLewanczyk, Dawid "/redfish/v1/" 501c5b2abe0SLewanczyk, Dawid "$metadata#ComputerSystemCollection.ComputerSystemCollection"; 502c5b2abe0SLewanczyk, Dawid Node::json["Name"] = "Computer System Collection"; 503c5b2abe0SLewanczyk, Dawid 504c5b2abe0SLewanczyk, Dawid entityPrivileges = { 505c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 506c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 507c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 508c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 509c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 510c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 511c5b2abe0SLewanczyk, Dawid } 512c5b2abe0SLewanczyk, Dawid 513c5b2abe0SLewanczyk, Dawid private: 51455c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 5151abe55efSEd Tanous const std::vector<std::string> ¶ms) override 5161abe55efSEd Tanous { 5176617338dSEd Tanous BMCWEB_LOG_DEBUG << "Get list of available boards."; 5186617338dSEd Tanous std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 5196617338dSEd Tanous res.jsonValue = Node::json; 5206617338dSEd Tanous crow::connections::systemBus->async_method_call( 5216617338dSEd Tanous [asyncResp](const boost::system::error_code ec, 5226617338dSEd Tanous const std::vector<std::string> &resp) { 5236617338dSEd Tanous if (ec) 5241abe55efSEd Tanous { 5256617338dSEd Tanous asyncResp->res.result( 5266617338dSEd Tanous boost::beast::http::status::internal_server_error); 5276617338dSEd Tanous return; 5286617338dSEd Tanous } 5296617338dSEd Tanous BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards."; 5306617338dSEd Tanous 531c5b2abe0SLewanczyk, Dawid // ... prepare json array with appropriate @odata.id links 5326617338dSEd Tanous nlohmann::json &boardArray = 5336617338dSEd Tanous asyncResp->res.jsonValue["Members"]; 5346617338dSEd Tanous boardArray = nlohmann::json::array(); 5356617338dSEd Tanous 5366617338dSEd Tanous // Iterate over all retrieved ObjectPaths. 5376617338dSEd Tanous for (const std::string &objpath : resp) 5386617338dSEd Tanous { 5396617338dSEd Tanous std::size_t lastPos = objpath.rfind("/"); 5406617338dSEd Tanous if (lastPos != std::string::npos) 5411abe55efSEd Tanous { 542c5b2abe0SLewanczyk, Dawid boardArray.push_back( 5436617338dSEd Tanous {{"@odata.id", "/redfish/v1/Systems/" + 5446617338dSEd Tanous objpath.substr(lastPos + 1)}}); 545c5b2abe0SLewanczyk, Dawid } 5461abe55efSEd Tanous } 5476617338dSEd Tanous 5486617338dSEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 5496617338dSEd Tanous boardArray.size(); 5506617338dSEd Tanous }, 5516617338dSEd Tanous "xyz.openbmc_project.ObjectMapper", 5526617338dSEd Tanous "/xyz/openbmc_project/object_mapper", 5536617338dSEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", 5546617338dSEd Tanous "/xyz/openbmc_project/inventory", int32_t(0), 5556617338dSEd Tanous std::array<const char *, 1>{ 5566617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.Board"}); 557c5b2abe0SLewanczyk, Dawid } 558c5b2abe0SLewanczyk, Dawid }; 559c5b2abe0SLewanczyk, Dawid 560c5b2abe0SLewanczyk, Dawid /** 561cc340dd9SEd Tanous * SystemActionsReset class supports handle POST method for Reset action. 562cc340dd9SEd Tanous * The class retrieves and sends data directly to D-Bus. 563cc340dd9SEd Tanous */ 564cc340dd9SEd Tanous class SystemActionsReset : public Node 565cc340dd9SEd Tanous { 566cc340dd9SEd Tanous public: 567cc340dd9SEd Tanous SystemActionsReset(CrowApp &app) : 568cc340dd9SEd Tanous Node(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/", 569cc340dd9SEd Tanous std::string()) 570cc340dd9SEd Tanous { 571cc340dd9SEd Tanous entityPrivileges = { 572cc340dd9SEd Tanous {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 573cc340dd9SEd Tanous } 574cc340dd9SEd Tanous 575cc340dd9SEd Tanous private: 576cc340dd9SEd Tanous /** 577cc340dd9SEd Tanous * Function handles POST method request. 578cc340dd9SEd Tanous * Analyzes POST body message before sends Reset request data to D-Bus. 579cc340dd9SEd Tanous */ 580cc340dd9SEd Tanous void doPost(crow::Response &res, const crow::Request &req, 581cc340dd9SEd Tanous const std::vector<std::string> ¶ms) override 582cc340dd9SEd Tanous { 583cc340dd9SEd Tanous // Parse JSON request body. 584cc340dd9SEd Tanous nlohmann::json post; 585cc340dd9SEd Tanous if (!json_util::processJsonFromRequest(res, req, post)) 586cc340dd9SEd Tanous { 587cc340dd9SEd Tanous return; 588cc340dd9SEd Tanous } 589cc340dd9SEd Tanous 590cc340dd9SEd Tanous auto asyncResp = std::make_shared<AsyncResp>(res); 591cc340dd9SEd Tanous 592cc340dd9SEd Tanous for (const auto &item : post.items()) 593cc340dd9SEd Tanous { 594cc340dd9SEd Tanous if (item.key() == "ResetType") 595cc340dd9SEd Tanous { 596cc340dd9SEd Tanous const std::string *reqResetType = 597cc340dd9SEd Tanous item.value().get_ptr<const std::string *>(); 598cc340dd9SEd Tanous if (reqResetType == nullptr) 599cc340dd9SEd Tanous { 600cc340dd9SEd Tanous res.result(boost::beast::http::status::bad_request); 601cc340dd9SEd Tanous messages::addMessageToErrorJson( 602cc340dd9SEd Tanous asyncResp->res.jsonValue, 603cc340dd9SEd Tanous messages::actionParameterValueFormatError( 604cc340dd9SEd Tanous item.value().dump(), "ResetType", 605cc340dd9SEd Tanous "ComputerSystem.Reset")); 606cc340dd9SEd Tanous res.end(); 607cc340dd9SEd Tanous return; 608cc340dd9SEd Tanous } 609cc340dd9SEd Tanous 610cc340dd9SEd Tanous if (*reqResetType == "ForceOff") 611cc340dd9SEd Tanous { 612cc340dd9SEd Tanous // Force off acts on the chassis 613cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 614cc340dd9SEd Tanous [asyncResp](const boost::system::error_code ec) { 615cc340dd9SEd Tanous if (ec) 616cc340dd9SEd Tanous { 617cc340dd9SEd Tanous BMCWEB_LOG_ERROR << "D-Bus responses error: " 618cc340dd9SEd Tanous << ec; 619cc340dd9SEd Tanous asyncResp->res.result( 620cc340dd9SEd Tanous boost::beast::http::status:: 621cc340dd9SEd Tanous internal_server_error); 622cc340dd9SEd Tanous return; 623cc340dd9SEd Tanous } 624cc340dd9SEd Tanous // TODO Consider support polling mechanism to verify 625cc340dd9SEd Tanous // status of host and chassis after execute the 626cc340dd9SEd Tanous // requested action. 627cc340dd9SEd Tanous BMCWEB_LOG_DEBUG << "Response with no content"; 628cc340dd9SEd Tanous asyncResp->res.result( 629cc340dd9SEd Tanous boost::beast::http::status::no_content); 630cc340dd9SEd Tanous }, 631cc340dd9SEd Tanous "xyz.openbmc_project.State.Chassis", 632cc340dd9SEd Tanous "/xyz/openbmc_project/state/chassis0", 633cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 634cc340dd9SEd Tanous "RequestedPowerTransition", 635cc340dd9SEd Tanous "xyz.openbmc_project.State.Chassis", 636cc340dd9SEd Tanous sdbusplus::message::variant<std::string>{ 637cc340dd9SEd Tanous "xyz.openbmc_project.State.Chassis.Transition." 638cc340dd9SEd Tanous "Off"}); 639cc340dd9SEd Tanous return; 640cc340dd9SEd Tanous } 641cc340dd9SEd Tanous // all other actions operate on the host 642cc340dd9SEd Tanous std::string command; 643cc340dd9SEd Tanous // Execute Reset Action regarding to each reset type. 644cc340dd9SEd Tanous if (*reqResetType == "On") 645cc340dd9SEd Tanous { 646cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 647cc340dd9SEd Tanous } 648cc340dd9SEd Tanous else if (*reqResetType == "GracefulShutdown") 649cc340dd9SEd Tanous { 650cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 651cc340dd9SEd Tanous } 652cc340dd9SEd Tanous else if (*reqResetType == "GracefulRestart") 653cc340dd9SEd Tanous { 654cc340dd9SEd Tanous command = 655cc340dd9SEd Tanous "xyz.openbmc_project.State.Host.Transition.Reboot"; 656cc340dd9SEd Tanous } 657cc340dd9SEd Tanous else 658cc340dd9SEd Tanous { 659cc340dd9SEd Tanous res.result(boost::beast::http::status::bad_request); 660cc340dd9SEd Tanous messages::addMessageToErrorJson( 661cc340dd9SEd Tanous asyncResp->res.jsonValue, 662cc340dd9SEd Tanous messages::actionParameterUnknown("Reset", 663cc340dd9SEd Tanous *reqResetType)); 664cc340dd9SEd Tanous res.end(); 665cc340dd9SEd Tanous return; 666cc340dd9SEd Tanous } 667cc340dd9SEd Tanous 668cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 669cc340dd9SEd Tanous [asyncResp](const boost::system::error_code ec) { 670cc340dd9SEd Tanous if (ec) 671cc340dd9SEd Tanous { 672cc340dd9SEd Tanous BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 673cc340dd9SEd Tanous asyncResp->res.result(boost::beast::http::status:: 674cc340dd9SEd Tanous internal_server_error); 675cc340dd9SEd Tanous return; 676cc340dd9SEd Tanous } 677cc340dd9SEd Tanous // TODO Consider support polling mechanism to verify 678cc340dd9SEd Tanous // status of host and chassis after execute the 679cc340dd9SEd Tanous // requested action. 680cc340dd9SEd Tanous BMCWEB_LOG_DEBUG << "Response with no content"; 681cc340dd9SEd Tanous asyncResp->res.result( 682cc340dd9SEd Tanous boost::beast::http::status::no_content); 683cc340dd9SEd Tanous }, 684cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 685cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 686cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 687cc340dd9SEd Tanous "RequestedHostTransition", "xyz.openbmc_project.State.Host", 688cc340dd9SEd Tanous sdbusplus::message::variant<std::string>{command}); 689cc340dd9SEd Tanous } 690cc340dd9SEd Tanous else 691cc340dd9SEd Tanous { 692cc340dd9SEd Tanous messages::addMessageToErrorJson( 693cc340dd9SEd Tanous asyncResp->res.jsonValue, 694cc340dd9SEd Tanous messages::actionParameterUnknown("ComputerSystem.Reset", 695cc340dd9SEd Tanous item.key())); 696cc340dd9SEd Tanous } 697cc340dd9SEd Tanous } 698cc340dd9SEd Tanous } 699cc340dd9SEd Tanous }; 700cc340dd9SEd Tanous 701cc340dd9SEd Tanous /** 7026617338dSEd Tanous * Systems derived class for delivering Computer Systems Schema. 703c5b2abe0SLewanczyk, Dawid */ 7041abe55efSEd Tanous class Systems : public Node 7051abe55efSEd Tanous { 706c5b2abe0SLewanczyk, Dawid public: 707c5b2abe0SLewanczyk, Dawid /* 708c5b2abe0SLewanczyk, Dawid * Default Constructor 709c5b2abe0SLewanczyk, Dawid */ 7101abe55efSEd Tanous Systems(CrowApp &app) : 7111abe55efSEd Tanous Node(app, "/redfish/v1/Systems/<str>/", std::string()) 7121abe55efSEd Tanous { 713c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem"; 714c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 715c5b2abe0SLewanczyk, Dawid "/redfish/v1/$metadata#ComputerSystem.ComputerSystem"; 716c5b2abe0SLewanczyk, Dawid Node::json["SystemType"] = "Physical"; 717c5b2abe0SLewanczyk, Dawid Node::json["Description"] = "Computer System"; 718c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideEnabled"] = 719c5b2abe0SLewanczyk, Dawid "Disabled"; // TODO(Dawid), get real boot data 720c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideTarget"] = 721c5b2abe0SLewanczyk, Dawid "None"; // TODO(Dawid), get real boot data 722c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideMode"] = 723c5b2abe0SLewanczyk, Dawid "Legacy"; // TODO(Dawid), get real boot data 7241abe55efSEd Tanous Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] = 7251abe55efSEd Tanous {"None", "Pxe", "Hdd", "Cd", 7261abe55efSEd Tanous "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot 7271abe55efSEd Tanous // data 728*04a258f4SEd Tanous Node::json["ProcessorSummary"]["Count"] = 0; 729c5b2abe0SLewanczyk, Dawid Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled"; 730c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0); 731c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["Status"]["State"] = "Disabled"; 732c5b2abe0SLewanczyk, Dawid entityPrivileges = { 733c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 734c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 735c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 736c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 737c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 738c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 739c5b2abe0SLewanczyk, Dawid } 740c5b2abe0SLewanczyk, Dawid 741c5b2abe0SLewanczyk, Dawid private: 742c5b2abe0SLewanczyk, Dawid /** 743c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 744c5b2abe0SLewanczyk, Dawid */ 74555c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 7461abe55efSEd Tanous const std::vector<std::string> ¶ms) override 7471abe55efSEd Tanous { 748c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 749c5b2abe0SLewanczyk, Dawid // impossible 7501abe55efSEd Tanous if (params.size() != 1) 7511abe55efSEd Tanous { 752c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 753c5b2abe0SLewanczyk, Dawid res.end(); 754c5b2abe0SLewanczyk, Dawid return; 755c5b2abe0SLewanczyk, Dawid } 756c5b2abe0SLewanczyk, Dawid 757c5b2abe0SLewanczyk, Dawid const std::string &name = params[0]; 758c5b2abe0SLewanczyk, Dawid 759*04a258f4SEd Tanous res.jsonValue = Node::json; 760*04a258f4SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 761*04a258f4SEd Tanous 762cc340dd9SEd Tanous // TODO Need to support ForceRestart. 763cc340dd9SEd Tanous res.jsonValue["Actions"]["#ComputerSystem.Reset"] = { 764cc340dd9SEd Tanous {"target", 765cc340dd9SEd Tanous "/redfish/v1/Systems/" + name + "/Actions/ComputerSystem.Reset"}, 766cc340dd9SEd Tanous {"ResetType@Redfish.AllowableValues", 767cc340dd9SEd Tanous {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}}; 768c5b2abe0SLewanczyk, Dawid 769a0803efaSEd Tanous auto asyncResp = std::make_shared<AsyncResp>(res); 770c5b2abe0SLewanczyk, Dawid 7716c34de48SEd Tanous getLedGroupIdentify( 772a0803efaSEd Tanous asyncResp, 773a0803efaSEd Tanous [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) { 7741abe55efSEd Tanous if (asserted) 7751abe55efSEd Tanous { 776c5b2abe0SLewanczyk, Dawid // If led group is asserted, then another call is needed to 777c5b2abe0SLewanczyk, Dawid // get led status 7786c34de48SEd Tanous getLedIdentify( 779a0803efaSEd Tanous aResp, [](const std::string &ledStatus, 780a0803efaSEd Tanous const std::shared_ptr<AsyncResp> &aResp) { 7811abe55efSEd Tanous if (!ledStatus.empty()) 7821abe55efSEd Tanous { 7831abe55efSEd Tanous aResp->res.jsonValue["IndicatorLED"] = 7841abe55efSEd Tanous ledStatus; 785c5b2abe0SLewanczyk, Dawid } 786c5b2abe0SLewanczyk, Dawid }); 7871abe55efSEd Tanous } 7881abe55efSEd Tanous else 7891abe55efSEd Tanous { 79055c7b7a2SEd Tanous aResp->res.jsonValue["IndicatorLED"] = "Off"; 791c5b2abe0SLewanczyk, Dawid } 792c5b2abe0SLewanczyk, Dawid }); 7936c34de48SEd Tanous getComputerSystem(asyncResp, name); 7946c34de48SEd Tanous getHostState(asyncResp); 795c5b2abe0SLewanczyk, Dawid } 796c5b2abe0SLewanczyk, Dawid 79755c7b7a2SEd Tanous void doPatch(crow::Response &res, const crow::Request &req, 7981abe55efSEd Tanous const std::vector<std::string> ¶ms) override 7991abe55efSEd Tanous { 800c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 801c5b2abe0SLewanczyk, Dawid // impossible 8026617338dSEd Tanous auto asyncResp = std::make_shared<AsyncResp>(res); 8031abe55efSEd Tanous if (params.size() != 1) 8041abe55efSEd Tanous { 805c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 806c5b2abe0SLewanczyk, Dawid return; 807c5b2abe0SLewanczyk, Dawid } 808c5b2abe0SLewanczyk, Dawid // Parse JSON request body 809c5b2abe0SLewanczyk, Dawid nlohmann::json patch; 8101abe55efSEd Tanous if (!json_util::processJsonFromRequest(res, req, patch)) 8111abe55efSEd Tanous { 812c5b2abe0SLewanczyk, Dawid return; 813c5b2abe0SLewanczyk, Dawid } 814c5b2abe0SLewanczyk, Dawid 8156617338dSEd Tanous const std::string &name = params[0]; 8166617338dSEd Tanous 81755c7b7a2SEd Tanous res.jsonValue = Node::json; 81855c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 819c5b2abe0SLewanczyk, Dawid 8206617338dSEd Tanous for (const auto &item : patch.items()) 8216617338dSEd Tanous { 8226617338dSEd Tanous if (item.key() == "IndicatorLed") 8236617338dSEd Tanous { 8246617338dSEd Tanous const std::string *reqLedState = 8256617338dSEd Tanous item.value().get_ptr<const std::string *>(); 8266617338dSEd Tanous if (reqLedState == nullptr) 8276617338dSEd Tanous { 8286617338dSEd Tanous messages::addMessageToErrorJson( 8296617338dSEd Tanous asyncResp->res.jsonValue, 8306617338dSEd Tanous messages::propertyValueFormatError(item.value().dump(), 8316617338dSEd Tanous item.key())); 8326617338dSEd Tanous return; 8336617338dSEd Tanous } 8346617338dSEd Tanous 8356617338dSEd Tanous // Verify key value 8366617338dSEd Tanous std::string dbusLedState; 8376617338dSEd Tanous if (*reqLedState == "On") 8386617338dSEd Tanous { 8396617338dSEd Tanous dbusLedState = 8406617338dSEd Tanous "xyz.openbmc_project.Led.Physical.Action.Lit"; 8416617338dSEd Tanous } 8426617338dSEd Tanous else if (*reqLedState == "Blink") 8436617338dSEd Tanous { 8446617338dSEd Tanous dbusLedState = 8456617338dSEd Tanous "xyz.openbmc_project.Led.Physical.Action.Blinking"; 8466617338dSEd Tanous } 8476617338dSEd Tanous else if (*reqLedState == "Off") 8486617338dSEd Tanous { 8496617338dSEd Tanous dbusLedState = 8506617338dSEd Tanous "xyz.openbmc_project.Led.Physical.Action.Off"; 8516617338dSEd Tanous } 8526617338dSEd Tanous else 8536617338dSEd Tanous { 8546617338dSEd Tanous messages::addMessageToJsonRoot( 8556617338dSEd Tanous res.jsonValue, messages::propertyValueNotInList( 8566617338dSEd Tanous *reqLedState, "IndicatorLED")); 8576617338dSEd Tanous return; 8586617338dSEd Tanous } 8596617338dSEd Tanous 8606c34de48SEd Tanous getHostState(asyncResp); 8616c34de48SEd Tanous getComputerSystem(asyncResp, name); 862c5b2abe0SLewanczyk, Dawid 863c5b2abe0SLewanczyk, Dawid // Update led group 86455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led group."; 86555c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 8666617338dSEd Tanous [asyncResp{std::move(asyncResp)}]( 867c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 8681abe55efSEd Tanous if (ec) 8691abe55efSEd Tanous { 87055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 8716617338dSEd Tanous asyncResp->res.result(boost::beast::http::status:: 8726617338dSEd Tanous internal_server_error); 873c5b2abe0SLewanczyk, Dawid return; 874c5b2abe0SLewanczyk, Dawid } 87555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led group update done."; 876c5b2abe0SLewanczyk, Dawid }, 877c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.GroupManager", 878c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/groups/enclosure_identify", 879c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 880c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Group", "Asserted", 881c5b2abe0SLewanczyk, Dawid sdbusplus::message::variant<bool>( 8826617338dSEd Tanous (dbusLedState == 8836617338dSEd Tanous "xyz.openbmc_project.Led.Physical.Action.Off" 8846617338dSEd Tanous ? false 8856617338dSEd Tanous : true))); 886c5b2abe0SLewanczyk, Dawid // Update identify led status 88755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection."; 88855c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 8896617338dSEd Tanous [asyncResp{std::move(asyncResp)}, 8906617338dSEd Tanous reqLedState{std::move(*reqLedState)}]( 891c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 8921abe55efSEd Tanous if (ec) 8931abe55efSEd Tanous { 89455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 8956617338dSEd Tanous asyncResp->res.result(boost::beast::http::status:: 8966617338dSEd Tanous internal_server_error); 897c5b2abe0SLewanczyk, Dawid return; 898c5b2abe0SLewanczyk, Dawid } 89955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led state update done."; 9006617338dSEd Tanous asyncResp->res.jsonValue["IndicatorLED"] = 9016617338dSEd Tanous std::move(reqLedState); 902c5b2abe0SLewanczyk, Dawid }, 903c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 904c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 905c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 906c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical", "State", 9076617338dSEd Tanous sdbusplus::message::variant<std::string>(dbusLedState)); 9086617338dSEd Tanous } 9096617338dSEd Tanous else 9106617338dSEd Tanous { 9116617338dSEd Tanous messages::addMessageToErrorJson( 9126617338dSEd Tanous asyncResp->res.jsonValue, 9136617338dSEd Tanous messages::propertyNotWritable(item.key())); 9146617338dSEd Tanous return; 9156617338dSEd Tanous } 916c5b2abe0SLewanczyk, Dawid } 917c5b2abe0SLewanczyk, Dawid } 918c5b2abe0SLewanczyk, Dawid }; 919c5b2abe0SLewanczyk, Dawid } // namespace redfish 920