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 18*1abe55efSEd Tanous #include "boost/container/flat_map.hpp" 19*1abe55efSEd Tanous #include "node.hpp" 20*1abe55efSEd Tanous 21c5b2abe0SLewanczyk, Dawid #include <error_messages.hpp> 22c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp> 23c5b2abe0SLewanczyk, Dawid 24*1abe55efSEd Tanous namespace redfish 25*1abe55efSEd Tanous { 26c5b2abe0SLewanczyk, Dawid 27c5b2abe0SLewanczyk, Dawid /** 28c5b2abe0SLewanczyk, Dawid * SystemAsyncResp 29c5b2abe0SLewanczyk, Dawid * Gathers data needed for response processing after async calls are done 30c5b2abe0SLewanczyk, Dawid */ 31*1abe55efSEd Tanous class SystemAsyncResp 32*1abe55efSEd Tanous { 33c5b2abe0SLewanczyk, Dawid public: 34*1abe55efSEd Tanous SystemAsyncResp(crow::Response &response) : res(response) 35*1abe55efSEd Tanous { 36*1abe55efSEd Tanous } 37c5b2abe0SLewanczyk, Dawid 38*1abe55efSEd Tanous ~SystemAsyncResp() 39*1abe55efSEd Tanous { 40*1abe55efSEd Tanous if (res.result() != (boost::beast::http::status::ok)) 41*1abe55efSEd Tanous { 42*1abe55efSEd Tanous // Reset the json object to clear out any data that made it in 43*1abe55efSEd Tanous // before the error happened todo(ed) handle error condition with 44*1abe55efSEd Tanous // proper code 4555c7b7a2SEd Tanous res.jsonValue = messages::internalError(); 46c5b2abe0SLewanczyk, Dawid } 47c5b2abe0SLewanczyk, Dawid res.end(); 48c5b2abe0SLewanczyk, Dawid } 49c5b2abe0SLewanczyk, Dawid 50*1abe55efSEd Tanous void setErrorStatus() 51*1abe55efSEd Tanous { 52c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 53c5b2abe0SLewanczyk, Dawid } 54c5b2abe0SLewanczyk, Dawid 5555c7b7a2SEd Tanous crow::Response &res; 56c5b2abe0SLewanczyk, Dawid }; 57c5b2abe0SLewanczyk, Dawid 58c5b2abe0SLewanczyk, Dawid /** 59c5b2abe0SLewanczyk, Dawid * OnDemandSystemsProvider 60c5b2abe0SLewanczyk, Dawid * Board provider class that retrieves data directly from dbus, before seting 61c5b2abe0SLewanczyk, Dawid * it into JSON output. This does not cache any data. 62c5b2abe0SLewanczyk, Dawid * 63c5b2abe0SLewanczyk, Dawid * Class can be a good example on how to scale different data providing 64c5b2abe0SLewanczyk, Dawid * solutions to produce single schema output. 65c5b2abe0SLewanczyk, Dawid * 66c5b2abe0SLewanczyk, Dawid * TODO(Pawel) 67c5b2abe0SLewanczyk, Dawid * This perhaps shall be different file, which has to be chosen on compile time 68c5b2abe0SLewanczyk, Dawid * depending on OEM needs 69c5b2abe0SLewanczyk, Dawid */ 70*1abe55efSEd Tanous class OnDemandSystemsProvider 71*1abe55efSEd Tanous { 72c5b2abe0SLewanczyk, Dawid public: 73c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 74*1abe55efSEd Tanous void getBaseboardList(CallbackFunc &&callback) 75*1abe55efSEd Tanous { 7655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get list of available boards."; 7755c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 78*1abe55efSEd Tanous [callback{std::move(callback)}]( 79*1abe55efSEd Tanous const boost::system::error_code ec, 80c5b2abe0SLewanczyk, Dawid const std::vector<std::string> &resp) { 81*1abe55efSEd Tanous // Callback requires vector<string> to retrieve all available 82*1abe55efSEd Tanous // board list. 83d76323e5SEd Tanous std::vector<std::string> boardList; 84*1abe55efSEd Tanous if (ec) 85*1abe55efSEd Tanous { 86*1abe55efSEd Tanous // Something wrong on DBus, the error_code is not important 87*1abe55efSEd Tanous // at this moment, just return success=false, and empty 88*1abe55efSEd Tanous // output. Since size of vector may vary depending on 89*1abe55efSEd Tanous // information from Entity Manager, and empty output could 90*1abe55efSEd Tanous // not be treated same way as error. 91d76323e5SEd Tanous callback(false, boardList); 92c5b2abe0SLewanczyk, Dawid return; 93c5b2abe0SLewanczyk, Dawid } 9455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards."; 95c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 96*1abe55efSEd Tanous for (const std::string &objpath : resp) 97*1abe55efSEd Tanous { 98d76323e5SEd Tanous std::size_t lastPos = objpath.rfind("/"); 99*1abe55efSEd Tanous if (lastPos != std::string::npos) 100*1abe55efSEd Tanous { 101d76323e5SEd Tanous boardList.emplace_back(objpath.substr(lastPos + 1)); 102c5b2abe0SLewanczyk, Dawid } 103c5b2abe0SLewanczyk, Dawid } 104c5b2abe0SLewanczyk, Dawid // Finally make a callback with useful data 105d76323e5SEd Tanous callback(true, boardList); 106c5b2abe0SLewanczyk, Dawid }, 107c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 108c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 109c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", 110c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/inventory", int32_t(0), 111c5b2abe0SLewanczyk, Dawid std::array<const char *, 1>{ 112c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.Board"}); 113c5b2abe0SLewanczyk, Dawid }; 114c5b2abe0SLewanczyk, Dawid 115c5b2abe0SLewanczyk, Dawid /** 116c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 117c5b2abe0SLewanczyk, Dawid * 118c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls 119c5b2abe0SLewanczyk, Dawid * @param[in] name Computer system name from request 120c5b2abe0SLewanczyk, Dawid * 121c5b2abe0SLewanczyk, Dawid * @return None. 122c5b2abe0SLewanczyk, Dawid */ 123c5b2abe0SLewanczyk, Dawid void getComputerSystem(std::shared_ptr<SystemAsyncResp> aResp, 124*1abe55efSEd Tanous const std::string &name) 125*1abe55efSEd Tanous { 126c5b2abe0SLewanczyk, Dawid const std::array<const char *, 5> interfaces = { 127c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Decorator.Asset", 128c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.Cpu", 129c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.Dimm", 130c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Inventory.Item.System", 131c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Common.UUID", 132c5b2abe0SLewanczyk, Dawid }; 13355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 13455c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 135c5b2abe0SLewanczyk, Dawid [name, aResp{std::move(aResp)}]( 136c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 137c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 138*1abe55efSEd Tanous std::string, std::vector<std::pair< 139*1abe55efSEd Tanous std::string, std::vector<std::string>>>>> 140c5b2abe0SLewanczyk, Dawid &subtree) { 141*1abe55efSEd Tanous if (ec) 142*1abe55efSEd Tanous { 14355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 144c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 145c5b2abe0SLewanczyk, Dawid return; 146c5b2abe0SLewanczyk, Dawid } 147c5b2abe0SLewanczyk, Dawid bool foundName = false; 148c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 149*1abe55efSEd Tanous for (const std::pair< 150*1abe55efSEd Tanous std::string, 151*1abe55efSEd Tanous std::vector< 152*1abe55efSEd Tanous std::pair<std::string, std::vector<std::string>>>> 153*1abe55efSEd Tanous &object : subtree) 154*1abe55efSEd Tanous { 155c5b2abe0SLewanczyk, Dawid const std::string &path = object.first; 15655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 157*1abe55efSEd Tanous const std::vector< 158*1abe55efSEd Tanous std::pair<std::string, std::vector<std::string>>> 159c5b2abe0SLewanczyk, Dawid &connectionNames = object.second; 160*1abe55efSEd Tanous if (connectionNames.size() < 1) 161*1abe55efSEd Tanous { 162c5b2abe0SLewanczyk, Dawid continue; 163c5b2abe0SLewanczyk, Dawid } 164c5b2abe0SLewanczyk, Dawid // Check if computer system exist 165*1abe55efSEd Tanous if (boost::ends_with(path, name)) 166*1abe55efSEd Tanous { 167c5b2abe0SLewanczyk, Dawid foundName = true; 16855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Found name: " << name; 169*1abe55efSEd Tanous const std::string connectionName = 170*1abe55efSEd Tanous connectionNames[0].first; 17155c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 172c5b2abe0SLewanczyk, Dawid [aResp, name(std::string(name))]( 173c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 174*1abe55efSEd Tanous const std::vector< 175*1abe55efSEd Tanous std::pair<std::string, VariantType>> 176c5b2abe0SLewanczyk, Dawid &propertiesList) { 177*1abe55efSEd Tanous if (ec) 178*1abe55efSEd Tanous { 179*1abe55efSEd Tanous BMCWEB_LOG_ERROR << "DBUS response error: " 180*1abe55efSEd Tanous << ec; 181c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 182c5b2abe0SLewanczyk, Dawid return; 183c5b2abe0SLewanczyk, Dawid } 184*1abe55efSEd Tanous BMCWEB_LOG_DEBUG << "Got " 185*1abe55efSEd Tanous << propertiesList.size() 186c5b2abe0SLewanczyk, Dawid << "properties for system"; 187*1abe55efSEd Tanous for (const std::pair<std::string, VariantType> 188*1abe55efSEd Tanous &property : propertiesList) 189*1abe55efSEd Tanous { 190c5b2abe0SLewanczyk, Dawid const std::string *value = 191*1abe55efSEd Tanous mapbox::getPtr<const std::string>( 192*1abe55efSEd Tanous property.second); 193*1abe55efSEd Tanous if (value != nullptr) 194*1abe55efSEd Tanous { 195*1abe55efSEd Tanous aResp->res.jsonValue[property.first] = 196*1abe55efSEd Tanous *value; 197c5b2abe0SLewanczyk, Dawid } 198c5b2abe0SLewanczyk, Dawid } 19955c7b7a2SEd Tanous aResp->res.jsonValue["Name"] = name; 20055c7b7a2SEd Tanous aResp->res.jsonValue["Id"] = 20155c7b7a2SEd Tanous aResp->res.jsonValue["SerialNumber"]; 202c5b2abe0SLewanczyk, Dawid }, 203*1abe55efSEd Tanous connectionName, path, 204*1abe55efSEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 205*1abe55efSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset"); 206*1abe55efSEd Tanous } 207*1abe55efSEd Tanous else 208*1abe55efSEd Tanous { 209*1abe55efSEd Tanous // This is not system, so check if it's cpu, dimm, UUID 210*1abe55efSEd Tanous // or BiosVer 211*1abe55efSEd Tanous for (auto const &s : connectionNames) 212*1abe55efSEd Tanous { 213*1abe55efSEd Tanous for (auto const &i : s.second) 214*1abe55efSEd Tanous { 215*1abe55efSEd Tanous if (boost::ends_with(i, "Dimm")) 216*1abe55efSEd Tanous { 217*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 218*1abe55efSEd Tanous << "Found Dimm, now get it properties."; 21955c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 220*1abe55efSEd Tanous [&, aResp]( 221*1abe55efSEd Tanous const boost::system::error_code ec, 222c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 223*1abe55efSEd Tanous std::string, VariantType>> 224*1abe55efSEd Tanous &properties) { 225*1abe55efSEd Tanous if (ec) 226*1abe55efSEd Tanous { 227*1abe55efSEd Tanous BMCWEB_LOG_ERROR 228*1abe55efSEd Tanous << "DBUS response error " 229*1abe55efSEd Tanous << ec; 230c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 231c5b2abe0SLewanczyk, Dawid return; 232c5b2abe0SLewanczyk, Dawid } 233*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 234*1abe55efSEd Tanous << "Got " << properties.size() 235c5b2abe0SLewanczyk, Dawid << "Dimm properties."; 236*1abe55efSEd Tanous for (const auto &p : properties) 237*1abe55efSEd Tanous { 238*1abe55efSEd Tanous if (p.first == "MemorySize") 239*1abe55efSEd Tanous { 240c5b2abe0SLewanczyk, Dawid const std::string *value = 241*1abe55efSEd Tanous mapbox::getPtr< 242*1abe55efSEd Tanous const std::string>( 243*1abe55efSEd Tanous p.second); 244*1abe55efSEd Tanous if ((value != nullptr) && 245*1abe55efSEd Tanous (*value != "NULL")) 246*1abe55efSEd Tanous { 247c5b2abe0SLewanczyk, Dawid // Remove units char 248c5b2abe0SLewanczyk, Dawid int32_t unitCoeff; 249*1abe55efSEd Tanous if (boost::ends_with( 250*1abe55efSEd Tanous *value, "MB")) 251*1abe55efSEd Tanous { 252c5b2abe0SLewanczyk, Dawid unitCoeff = 1000; 253*1abe55efSEd Tanous } 254*1abe55efSEd Tanous else if (boost:: 255*1abe55efSEd Tanous ends_with( 256*1abe55efSEd Tanous *value, 257*1abe55efSEd Tanous "KB")) 258*1abe55efSEd Tanous { 259c5b2abe0SLewanczyk, Dawid unitCoeff = 1000000; 260*1abe55efSEd Tanous } 261*1abe55efSEd Tanous else 262*1abe55efSEd Tanous { 263a434f2bdSEd Tanous BMCWEB_LOG_ERROR 264*1abe55efSEd Tanous << "Unsupported" 265*1abe55efSEd Tanous " memory " 266*1abe55efSEd Tanous "units"; 267*1abe55efSEd Tanous aResp 268*1abe55efSEd Tanous ->setErrorStatus(); 269c5b2abe0SLewanczyk, Dawid return; 270c5b2abe0SLewanczyk, Dawid } 271c5b2abe0SLewanczyk, Dawid 272*1abe55efSEd Tanous auto memSize = 273*1abe55efSEd Tanous boost::lexical_cast< 274*1abe55efSEd Tanous int>(value->substr( 275*1abe55efSEd Tanous 0, 276*1abe55efSEd Tanous value->length() - 277*1abe55efSEd Tanous 2)); 278*1abe55efSEd Tanous aResp->res.jsonValue 279*1abe55efSEd Tanous ["TotalSystemMemory" 280*1abe55efSEd Tanous "GiB"] += 281c5b2abe0SLewanczyk, Dawid memSize * unitCoeff; 282*1abe55efSEd Tanous aResp->res.jsonValue 283*1abe55efSEd Tanous ["MemorySummary"] 284*1abe55efSEd Tanous ["Status"] 285*1abe55efSEd Tanous ["State"] = 286*1abe55efSEd Tanous "Enabled"; 287c5b2abe0SLewanczyk, Dawid } 288c5b2abe0SLewanczyk, Dawid } 289c5b2abe0SLewanczyk, Dawid } 290c5b2abe0SLewanczyk, Dawid }, 291*1abe55efSEd Tanous s.first, path, 292*1abe55efSEd Tanous "org.freedesktop.DBus.Properties", 293*1abe55efSEd Tanous "GetAll", 294*1abe55efSEd Tanous "xyz.openbmc_project.Inventory.Item." 295*1abe55efSEd Tanous "Dimm"); 296*1abe55efSEd Tanous } 297*1abe55efSEd Tanous else if (boost::ends_with(i, "Cpu")) 298*1abe55efSEd Tanous { 299*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 300*1abe55efSEd Tanous << "Found Cpu, now get it properties."; 301*1abe55efSEd Tanous crow::connections::systemBus 302*1abe55efSEd Tanous ->async_method_call( 303*1abe55efSEd Tanous [&, aResp]( 304*1abe55efSEd Tanous const boost::system::error_code 305*1abe55efSEd Tanous ec, 306c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 307*1abe55efSEd Tanous std::string, VariantType>> 308*1abe55efSEd Tanous &properties) { 309*1abe55efSEd Tanous if (ec) 310*1abe55efSEd Tanous { 311*1abe55efSEd Tanous BMCWEB_LOG_ERROR 312*1abe55efSEd Tanous << "DBUS response " 313*1abe55efSEd Tanous "error " 314*1abe55efSEd Tanous << ec; 315c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 316c5b2abe0SLewanczyk, Dawid return; 317c5b2abe0SLewanczyk, Dawid } 318*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 319*1abe55efSEd Tanous << "Got " 320*1abe55efSEd Tanous << properties.size() 321c5b2abe0SLewanczyk, Dawid << "Cpu properties."; 322*1abe55efSEd Tanous for (const auto &p : properties) 323*1abe55efSEd Tanous { 324*1abe55efSEd Tanous if (p.first == 325*1abe55efSEd Tanous "ProcessorFamily") 326*1abe55efSEd Tanous { 327*1abe55efSEd Tanous const std::string 328*1abe55efSEd Tanous *value = 329*1abe55efSEd Tanous mapbox::getPtr< 330*1abe55efSEd Tanous const std:: 331*1abe55efSEd Tanous string>( 332*1abe55efSEd Tanous p.second); 333*1abe55efSEd Tanous if (value != nullptr) 334*1abe55efSEd Tanous { 335*1abe55efSEd Tanous aResp->res.jsonValue 336*1abe55efSEd Tanous ["ProcessorSumm" 337*1abe55efSEd Tanous "ary"] 338*1abe55efSEd Tanous ["Count"] = 339c5b2abe0SLewanczyk, Dawid aResp->res 340*1abe55efSEd Tanous .jsonValue 341*1abe55efSEd Tanous ["Proce" 342*1abe55efSEd Tanous "ssorS" 343*1abe55efSEd Tanous "ummar" 344*1abe55efSEd Tanous "y"] 345*1abe55efSEd Tanous ["Coun" 346*1abe55efSEd Tanous "t"] 347*1abe55efSEd Tanous .get< 348*1abe55efSEd Tanous int>() + 349c5b2abe0SLewanczyk, Dawid 1; 350*1abe55efSEd Tanous aResp->res.jsonValue 351*1abe55efSEd Tanous ["ProcessorSumm" 352*1abe55efSEd Tanous "ary"] 353*1abe55efSEd Tanous ["Status"] 354*1abe55efSEd Tanous ["State"] = 355c5b2abe0SLewanczyk, Dawid "Enabled"; 356*1abe55efSEd Tanous aResp->res.jsonValue 357*1abe55efSEd Tanous ["ProcessorSumm" 358*1abe55efSEd Tanous "ary"] 359*1abe55efSEd Tanous ["Model"] = 360c5b2abe0SLewanczyk, Dawid *value; 361c5b2abe0SLewanczyk, Dawid } 362c5b2abe0SLewanczyk, Dawid } 363c5b2abe0SLewanczyk, Dawid } 364c5b2abe0SLewanczyk, Dawid }, 365*1abe55efSEd Tanous s.first, path, 366*1abe55efSEd Tanous "org.freedesktop.DBus.Properties", 367*1abe55efSEd Tanous "GetAll", 368*1abe55efSEd Tanous "xyz.openbmc_project.Inventory." 369*1abe55efSEd Tanous "Item.Cpu"); 370*1abe55efSEd Tanous } 371*1abe55efSEd Tanous else if (boost::ends_with(i, "UUID")) 372*1abe55efSEd Tanous { 373*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 374*1abe55efSEd Tanous << "Found UUID, now get it properties."; 37555c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 376*1abe55efSEd Tanous [aResp]( 377*1abe55efSEd Tanous const boost::system::error_code ec, 378c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 379*1abe55efSEd Tanous std::string, VariantType>> 380*1abe55efSEd Tanous &properties) { 381*1abe55efSEd Tanous if (ec) 382*1abe55efSEd Tanous { 383*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 384*1abe55efSEd Tanous << "DBUS response error " 385*1abe55efSEd Tanous << ec; 386c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 387c5b2abe0SLewanczyk, Dawid return; 388c5b2abe0SLewanczyk, Dawid } 389*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 390*1abe55efSEd Tanous << "Got " << properties.size() 391c5b2abe0SLewanczyk, Dawid << "UUID properties."; 392*1abe55efSEd Tanous for (const std::pair<std::string, 393*1abe55efSEd Tanous VariantType> 394*1abe55efSEd Tanous &p : properties) 395*1abe55efSEd Tanous { 396*1abe55efSEd Tanous if (p.first == "BIOSVer") 397*1abe55efSEd Tanous { 398c5b2abe0SLewanczyk, Dawid const std::string *value = 399*1abe55efSEd Tanous mapbox::getPtr< 400*1abe55efSEd Tanous const std::string>( 401*1abe55efSEd Tanous p.second); 402*1abe55efSEd Tanous if (value != nullptr) 403*1abe55efSEd Tanous { 404*1abe55efSEd Tanous aResp->res.jsonValue 405*1abe55efSEd Tanous ["BiosVersion"] = 406*1abe55efSEd Tanous *value; 407c5b2abe0SLewanczyk, Dawid } 408c5b2abe0SLewanczyk, Dawid } 409*1abe55efSEd Tanous if (p.first == "UUID") 410*1abe55efSEd Tanous { 411c5b2abe0SLewanczyk, Dawid const std::string *value = 412*1abe55efSEd Tanous mapbox::getPtr< 413*1abe55efSEd Tanous const std::string>( 414*1abe55efSEd Tanous p.second); 415*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 416*1abe55efSEd Tanous << "UUID = " << *value 417*1abe55efSEd Tanous << " length " 418*1abe55efSEd Tanous << value->length(); 419*1abe55efSEd Tanous if (value != nullptr) 420*1abe55efSEd Tanous { 421*1abe55efSEd Tanous // Workaround for to 422*1abe55efSEd Tanous // short return str in 423*1abe55efSEd Tanous // smbios demo app, 32 424*1abe55efSEd Tanous // bytes are described 425*1abe55efSEd Tanous // by spec 426*1abe55efSEd Tanous if (value->length() > 427*1abe55efSEd Tanous 0 && 428*1abe55efSEd Tanous value->length() < 429*1abe55efSEd Tanous 32) 430*1abe55efSEd Tanous { 431*1abe55efSEd Tanous std::string 432*1abe55efSEd Tanous correctedValue = 433*1abe55efSEd Tanous *value; 434*1abe55efSEd Tanous correctedValue.append( 435*1abe55efSEd Tanous 32 - 436*1abe55efSEd Tanous value 437*1abe55efSEd Tanous ->length(), 438c5b2abe0SLewanczyk, Dawid '0'); 439*1abe55efSEd Tanous value = 440*1abe55efSEd Tanous &correctedValue; 441*1abe55efSEd Tanous } 442*1abe55efSEd Tanous else if ( 443*1abe55efSEd Tanous value->length() == 444*1abe55efSEd Tanous 32) 445*1abe55efSEd Tanous { 446*1abe55efSEd Tanous aResp->res.jsonValue 447*1abe55efSEd Tanous ["UUID"] = 448*1abe55efSEd Tanous value->substr( 449*1abe55efSEd Tanous 0, 8) + 450*1abe55efSEd Tanous "-" + 451*1abe55efSEd Tanous value->substr( 452*1abe55efSEd Tanous 8, 4) + 453*1abe55efSEd Tanous "-" + 454*1abe55efSEd Tanous value->substr( 455*1abe55efSEd Tanous 12, 4) + 456*1abe55efSEd Tanous "-" + 457*1abe55efSEd Tanous value->substr( 458*1abe55efSEd Tanous 16, 4) + 459*1abe55efSEd Tanous "-" + 460*1abe55efSEd Tanous value->substr( 461*1abe55efSEd Tanous 20, 12); 462c5b2abe0SLewanczyk, Dawid } 463c5b2abe0SLewanczyk, Dawid } 464c5b2abe0SLewanczyk, Dawid } 465c5b2abe0SLewanczyk, Dawid } 466c5b2abe0SLewanczyk, Dawid }, 467*1abe55efSEd Tanous s.first, path, 468*1abe55efSEd Tanous "org.freedesktop.DBus.Properties", 469*1abe55efSEd Tanous "GetAll", 470*1abe55efSEd Tanous "xyz.openbmc_project.Common.UUID"); 471c5b2abe0SLewanczyk, Dawid } 472c5b2abe0SLewanczyk, Dawid } 473c5b2abe0SLewanczyk, Dawid } 474c5b2abe0SLewanczyk, Dawid } 475c5b2abe0SLewanczyk, Dawid } 476*1abe55efSEd Tanous if (foundName == false) 477*1abe55efSEd Tanous { 478c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 479c5b2abe0SLewanczyk, Dawid } 480c5b2abe0SLewanczyk, Dawid }, 481c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 482c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 483c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTree", 484c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/inventory", int32_t(0), interfaces); 485c5b2abe0SLewanczyk, Dawid } 486c5b2abe0SLewanczyk, Dawid 487c5b2abe0SLewanczyk, Dawid /** 488c5b2abe0SLewanczyk, Dawid * @brief Retrieves identify led group properties over dbus 489c5b2abe0SLewanczyk, Dawid * 490c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 491c5b2abe0SLewanczyk, Dawid * @param[in] callback Callback for process retrieved data. 492c5b2abe0SLewanczyk, Dawid * 493c5b2abe0SLewanczyk, Dawid * @return None. 494c5b2abe0SLewanczyk, Dawid */ 495c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 496c5b2abe0SLewanczyk, Dawid void getLedGroupIdentify(std::shared_ptr<SystemAsyncResp> aResp, 497*1abe55efSEd Tanous CallbackFunc &&callback) 498*1abe55efSEd Tanous { 49955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get led groups"; 50055c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 501*1abe55efSEd Tanous [aResp{std::move(aResp)}, 502*1abe55efSEd Tanous &callback](const boost::system::error_code &ec, 503*1abe55efSEd Tanous const ManagedObjectsType &resp) { 504*1abe55efSEd Tanous if (ec) 505*1abe55efSEd Tanous { 50655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 507c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 508c5b2abe0SLewanczyk, Dawid return; 509c5b2abe0SLewanczyk, Dawid } 510*1abe55efSEd Tanous BMCWEB_LOG_DEBUG << "Got " << resp.size() 511*1abe55efSEd Tanous << "led group objects."; 512*1abe55efSEd Tanous for (const auto &objPath : resp) 513*1abe55efSEd Tanous { 514c5b2abe0SLewanczyk, Dawid const std::string &path = objPath.first; 515*1abe55efSEd Tanous if (path.rfind("enclosure_identify") != std::string::npos) 516*1abe55efSEd Tanous { 517*1abe55efSEd Tanous for (const auto &interface : objPath.second) 518*1abe55efSEd Tanous { 519*1abe55efSEd Tanous if (interface.first == 520*1abe55efSEd Tanous "xyz.openbmc_project.Led.Group") 521*1abe55efSEd Tanous { 522*1abe55efSEd Tanous for (const auto &property : interface.second) 523*1abe55efSEd Tanous { 524*1abe55efSEd Tanous if (property.first == "Asserted") 525*1abe55efSEd Tanous { 526c5b2abe0SLewanczyk, Dawid const bool *asserted = 527*1abe55efSEd Tanous mapbox::getPtr<const bool>( 528*1abe55efSEd Tanous property.second); 529*1abe55efSEd Tanous if (nullptr != asserted) 530*1abe55efSEd Tanous { 531c5b2abe0SLewanczyk, Dawid callback(*asserted, aResp); 532*1abe55efSEd Tanous } 533*1abe55efSEd Tanous else 534*1abe55efSEd Tanous { 535c5b2abe0SLewanczyk, Dawid callback(false, aResp); 536c5b2abe0SLewanczyk, Dawid } 537c5b2abe0SLewanczyk, Dawid } 538c5b2abe0SLewanczyk, Dawid } 539c5b2abe0SLewanczyk, Dawid } 540c5b2abe0SLewanczyk, Dawid } 541c5b2abe0SLewanczyk, Dawid } 542c5b2abe0SLewanczyk, Dawid } 543c5b2abe0SLewanczyk, Dawid }, 544c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.GroupManager", 545*1abe55efSEd Tanous "/xyz/openbmc_project/led/groups", 546*1abe55efSEd Tanous "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 547c5b2abe0SLewanczyk, Dawid } 548c5b2abe0SLewanczyk, Dawid 549c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc> 550c5b2abe0SLewanczyk, Dawid void getLedIdentify(std::shared_ptr<SystemAsyncResp> aResp, 551*1abe55efSEd Tanous CallbackFunc &&callback) 552*1abe55efSEd Tanous { 55355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get identify led properties"; 55455c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 555*1abe55efSEd Tanous [aResp{std::move(aResp)}, 556*1abe55efSEd Tanous &callback](const boost::system::error_code ec, 557c5b2abe0SLewanczyk, Dawid const PropertiesType &properties) { 558*1abe55efSEd Tanous if (ec) 559*1abe55efSEd Tanous { 56055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 561c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 562c5b2abe0SLewanczyk, Dawid return; 563c5b2abe0SLewanczyk, Dawid } 564*1abe55efSEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 565*1abe55efSEd Tanous << "led properties."; 566c5b2abe0SLewanczyk, Dawid std::string output; 567*1abe55efSEd Tanous for (const auto &property : properties) 568*1abe55efSEd Tanous { 569*1abe55efSEd Tanous if (property.first == "State") 570*1abe55efSEd Tanous { 571c5b2abe0SLewanczyk, Dawid const std::string *s = 57255c7b7a2SEd Tanous mapbox::getPtr<std::string>(property.second); 573*1abe55efSEd Tanous if (nullptr != s) 574*1abe55efSEd Tanous { 57555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Identify Led State: " << *s; 576c5b2abe0SLewanczyk, Dawid const auto pos = s->rfind('.'); 577*1abe55efSEd Tanous if (pos != std::string::npos) 578*1abe55efSEd Tanous { 579c5b2abe0SLewanczyk, Dawid auto led = s->substr(pos + 1); 580*1abe55efSEd Tanous for (const std::pair<const char *, const char *> 581*1abe55efSEd Tanous &p : 582*1abe55efSEd Tanous std::array< 583*1abe55efSEd Tanous std::pair<const char *, const char *>, 584*1abe55efSEd Tanous 3>{{{"On", "Lit"}, 585c5b2abe0SLewanczyk, Dawid {"Blink", "Blinking"}, 586*1abe55efSEd Tanous {"Off", "Off"}}}) 587*1abe55efSEd Tanous { 588*1abe55efSEd Tanous if (led == p.first) 589*1abe55efSEd Tanous { 590c5b2abe0SLewanczyk, Dawid output = p.second; 591c5b2abe0SLewanczyk, Dawid } 592c5b2abe0SLewanczyk, Dawid } 593c5b2abe0SLewanczyk, Dawid } 594c5b2abe0SLewanczyk, Dawid } 595c5b2abe0SLewanczyk, Dawid } 596c5b2abe0SLewanczyk, Dawid } 597c5b2abe0SLewanczyk, Dawid callback(output, aResp); 598c5b2abe0SLewanczyk, Dawid }, 599c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 600c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 601c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "GetAll", 602c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical"); 603c5b2abe0SLewanczyk, Dawid } 604c5b2abe0SLewanczyk, Dawid 605c5b2abe0SLewanczyk, Dawid /** 606c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 607c5b2abe0SLewanczyk, Dawid * 608c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 609c5b2abe0SLewanczyk, Dawid * 610c5b2abe0SLewanczyk, Dawid * @return None. 611c5b2abe0SLewanczyk, Dawid */ 612*1abe55efSEd Tanous void getHostState(std::shared_ptr<SystemAsyncResp> aResp) 613*1abe55efSEd Tanous { 61455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 61555c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 616c5b2abe0SLewanczyk, Dawid [aResp{std::move(aResp)}](const boost::system::error_code ec, 617c5b2abe0SLewanczyk, Dawid const PropertiesType &properties) { 618*1abe55efSEd Tanous if (ec) 619*1abe55efSEd Tanous { 62055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 621c5b2abe0SLewanczyk, Dawid aResp->setErrorStatus(); 622c5b2abe0SLewanczyk, Dawid return; 623c5b2abe0SLewanczyk, Dawid } 624*1abe55efSEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 625*1abe55efSEd Tanous << "host properties."; 626*1abe55efSEd Tanous for (const auto &property : properties) 627*1abe55efSEd Tanous { 628*1abe55efSEd Tanous if (property.first == "CurrentHostState") 629*1abe55efSEd Tanous { 630c5b2abe0SLewanczyk, Dawid const std::string *s = 63155c7b7a2SEd Tanous mapbox::getPtr<const std::string>(property.second); 63255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Host state: " << *s; 633*1abe55efSEd Tanous if (nullptr != s) 634*1abe55efSEd Tanous { 635c5b2abe0SLewanczyk, Dawid const auto pos = s->rfind('.'); 636*1abe55efSEd Tanous if (pos != std::string::npos) 637*1abe55efSEd Tanous { 638c5b2abe0SLewanczyk, Dawid // Verify Host State 639*1abe55efSEd Tanous if (s->substr(pos + 1) == "Running") 640*1abe55efSEd Tanous { 64155c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 642*1abe55efSEd Tanous aResp->res.jsonValue["Status"]["State"] = 643*1abe55efSEd Tanous "Enabled"; 644*1abe55efSEd Tanous } 645*1abe55efSEd Tanous else 646*1abe55efSEd Tanous { 64755c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 648*1abe55efSEd Tanous aResp->res.jsonValue["Status"]["State"] = 649*1abe55efSEd Tanous "Disabled"; 650c5b2abe0SLewanczyk, Dawid } 651c5b2abe0SLewanczyk, Dawid } 652c5b2abe0SLewanczyk, Dawid } 653c5b2abe0SLewanczyk, Dawid } 654c5b2abe0SLewanczyk, Dawid } 655c5b2abe0SLewanczyk, Dawid }, 656*1abe55efSEd Tanous "xyz.openbmc_project.State.Host", 657*1abe55efSEd Tanous "/xyz/openbmc_project/state/host0", 658c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "GetAll", 659c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.State.Host"); 660c5b2abe0SLewanczyk, Dawid } 661c5b2abe0SLewanczyk, Dawid }; 662c5b2abe0SLewanczyk, Dawid 663c5b2abe0SLewanczyk, Dawid /** 664c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 665c5b2abe0SLewanczyk, Dawid * Schema 666c5b2abe0SLewanczyk, Dawid */ 667*1abe55efSEd Tanous class SystemsCollection : public Node 668*1abe55efSEd Tanous { 669c5b2abe0SLewanczyk, Dawid public: 670*1abe55efSEd Tanous SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/") 671*1abe55efSEd Tanous { 672c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = 673c5b2abe0SLewanczyk, Dawid "#ComputerSystemCollection.ComputerSystemCollection"; 674c5b2abe0SLewanczyk, Dawid Node::json["@odata.id"] = "/redfish/v1/Systems"; 675c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 676c5b2abe0SLewanczyk, Dawid "/redfish/v1/" 677c5b2abe0SLewanczyk, Dawid "$metadata#ComputerSystemCollection.ComputerSystemCollection"; 678c5b2abe0SLewanczyk, Dawid Node::json["Name"] = "Computer System Collection"; 679c5b2abe0SLewanczyk, Dawid 680c5b2abe0SLewanczyk, Dawid entityPrivileges = { 681c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 682c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 683c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 684c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 685c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 686c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 687c5b2abe0SLewanczyk, Dawid } 688c5b2abe0SLewanczyk, Dawid 689c5b2abe0SLewanczyk, Dawid private: 690c5b2abe0SLewanczyk, Dawid /** 691c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 692c5b2abe0SLewanczyk, Dawid */ 69355c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 694*1abe55efSEd Tanous const std::vector<std::string> ¶ms) override 695*1abe55efSEd Tanous { 696c5b2abe0SLewanczyk, Dawid // Get board list, and call the below callback for JSON preparation 697*1abe55efSEd Tanous provider.getBaseboardList([&](const bool &success, 698*1abe55efSEd Tanous const std::vector<std::string> &output) { 699*1abe55efSEd Tanous if (success) 700*1abe55efSEd Tanous { 701c5b2abe0SLewanczyk, Dawid // ... prepare json array with appropriate @odata.id links 702c5b2abe0SLewanczyk, Dawid nlohmann::json boardArray = nlohmann::json::array(); 703*1abe55efSEd Tanous for (const std::string &boardItem : output) 704*1abe55efSEd Tanous { 705c5b2abe0SLewanczyk, Dawid boardArray.push_back( 706d76323e5SEd Tanous {{"@odata.id", "/redfish/v1/Systems/" + boardItem}}); 707c5b2abe0SLewanczyk, Dawid } 708c5b2abe0SLewanczyk, Dawid // Then attach members, count size and return, 709c5b2abe0SLewanczyk, Dawid Node::json["Members"] = boardArray; 710c5b2abe0SLewanczyk, Dawid Node::json["Members@odata.count"] = boardArray.size(); 71155c7b7a2SEd Tanous res.jsonValue = Node::json; 712*1abe55efSEd Tanous } 713*1abe55efSEd Tanous else 714*1abe55efSEd Tanous { 715c5b2abe0SLewanczyk, Dawid // ... otherwise, return INTERNALL ERROR 716c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 717c5b2abe0SLewanczyk, Dawid } 718c5b2abe0SLewanczyk, Dawid res.end(); 719c5b2abe0SLewanczyk, Dawid }); 720c5b2abe0SLewanczyk, Dawid } 721c5b2abe0SLewanczyk, Dawid 722c5b2abe0SLewanczyk, Dawid OnDemandSystemsProvider provider; 723c5b2abe0SLewanczyk, Dawid }; 724c5b2abe0SLewanczyk, Dawid 725c5b2abe0SLewanczyk, Dawid /** 726c5b2abe0SLewanczyk, Dawid * Systems override class for delivering ComputerSystems Schema 727c5b2abe0SLewanczyk, Dawid */ 728*1abe55efSEd Tanous class Systems : public Node 729*1abe55efSEd Tanous { 730c5b2abe0SLewanczyk, Dawid public: 731c5b2abe0SLewanczyk, Dawid /* 732c5b2abe0SLewanczyk, Dawid * Default Constructor 733c5b2abe0SLewanczyk, Dawid */ 734*1abe55efSEd Tanous Systems(CrowApp &app) : 735*1abe55efSEd Tanous Node(app, "/redfish/v1/Systems/<str>/", std::string()) 736*1abe55efSEd Tanous { 737c5b2abe0SLewanczyk, Dawid Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem"; 738c5b2abe0SLewanczyk, Dawid Node::json["@odata.context"] = 739c5b2abe0SLewanczyk, Dawid "/redfish/v1/$metadata#ComputerSystem.ComputerSystem"; 740c5b2abe0SLewanczyk, Dawid Node::json["SystemType"] = "Physical"; 741c5b2abe0SLewanczyk, Dawid Node::json["Description"] = "Computer System"; 742c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideEnabled"] = 743c5b2abe0SLewanczyk, Dawid "Disabled"; // TODO(Dawid), get real boot data 744c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideTarget"] = 745c5b2abe0SLewanczyk, Dawid "None"; // TODO(Dawid), get real boot data 746c5b2abe0SLewanczyk, Dawid Node::json["Boot"]["BootSourceOverrideMode"] = 747c5b2abe0SLewanczyk, Dawid "Legacy"; // TODO(Dawid), get real boot data 748*1abe55efSEd Tanous Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] = 749*1abe55efSEd Tanous {"None", "Pxe", "Hdd", "Cd", 750*1abe55efSEd Tanous "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot 751*1abe55efSEd Tanous // data 752c5b2abe0SLewanczyk, Dawid Node::json["ProcessorSummary"]["Count"] = int(0); 753c5b2abe0SLewanczyk, Dawid Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled"; 754c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0); 755c5b2abe0SLewanczyk, Dawid Node::json["MemorySummary"]["Status"]["State"] = "Disabled"; 756c5b2abe0SLewanczyk, Dawid 757c5b2abe0SLewanczyk, Dawid entityPrivileges = { 758c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::get, {{"Login"}}}, 759c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::head, {{"Login"}}}, 760c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 761c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 762c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 763c5b2abe0SLewanczyk, Dawid {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 764c5b2abe0SLewanczyk, Dawid } 765c5b2abe0SLewanczyk, Dawid 766c5b2abe0SLewanczyk, Dawid private: 767c5b2abe0SLewanczyk, Dawid OnDemandSystemsProvider provider; 768c5b2abe0SLewanczyk, Dawid 769c5b2abe0SLewanczyk, Dawid /** 770c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 771c5b2abe0SLewanczyk, Dawid */ 77255c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 773*1abe55efSEd Tanous const std::vector<std::string> ¶ms) override 774*1abe55efSEd Tanous { 775c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 776c5b2abe0SLewanczyk, Dawid // impossible 777*1abe55efSEd Tanous if (params.size() != 1) 778*1abe55efSEd Tanous { 779c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 780c5b2abe0SLewanczyk, Dawid res.end(); 781c5b2abe0SLewanczyk, Dawid return; 782c5b2abe0SLewanczyk, Dawid } 783c5b2abe0SLewanczyk, Dawid 784c5b2abe0SLewanczyk, Dawid const std::string &name = params[0]; 785c5b2abe0SLewanczyk, Dawid 78655c7b7a2SEd Tanous res.jsonValue = Node::json; 78755c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 788c5b2abe0SLewanczyk, Dawid 789c5b2abe0SLewanczyk, Dawid auto asyncResp = std::make_shared<SystemAsyncResp>(res); 790c5b2abe0SLewanczyk, Dawid 791c5b2abe0SLewanczyk, Dawid provider.getLedGroupIdentify( 792c5b2abe0SLewanczyk, Dawid asyncResp, [&](const bool &asserted, 793c5b2abe0SLewanczyk, Dawid const std::shared_ptr<SystemAsyncResp> &aResp) { 794*1abe55efSEd Tanous if (asserted) 795*1abe55efSEd Tanous { 796c5b2abe0SLewanczyk, Dawid // If led group is asserted, then another call is needed to 797c5b2abe0SLewanczyk, Dawid // get led status 798c5b2abe0SLewanczyk, Dawid provider.getLedIdentify( 799*1abe55efSEd Tanous aResp, 800*1abe55efSEd Tanous [](const std::string &ledStatus, 801c5b2abe0SLewanczyk, Dawid const std::shared_ptr<SystemAsyncResp> &aResp) { 802*1abe55efSEd Tanous if (!ledStatus.empty()) 803*1abe55efSEd Tanous { 804*1abe55efSEd Tanous aResp->res.jsonValue["IndicatorLED"] = 805*1abe55efSEd Tanous ledStatus; 806c5b2abe0SLewanczyk, Dawid } 807c5b2abe0SLewanczyk, Dawid }); 808*1abe55efSEd Tanous } 809*1abe55efSEd Tanous else 810*1abe55efSEd Tanous { 81155c7b7a2SEd Tanous aResp->res.jsonValue["IndicatorLED"] = "Off"; 812c5b2abe0SLewanczyk, Dawid } 813c5b2abe0SLewanczyk, Dawid }); 814c5b2abe0SLewanczyk, Dawid provider.getComputerSystem(asyncResp, name); 815c5b2abe0SLewanczyk, Dawid provider.getHostState(asyncResp); 816c5b2abe0SLewanczyk, Dawid } 817c5b2abe0SLewanczyk, Dawid 81855c7b7a2SEd Tanous void doPatch(crow::Response &res, const crow::Request &req, 819*1abe55efSEd Tanous const std::vector<std::string> ¶ms) override 820*1abe55efSEd Tanous { 821c5b2abe0SLewanczyk, Dawid // Check if there is required param, truly entering this shall be 822c5b2abe0SLewanczyk, Dawid // impossible 823*1abe55efSEd Tanous if (params.size() != 1) 824*1abe55efSEd Tanous { 825c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::internal_server_error); 826c5b2abe0SLewanczyk, Dawid res.end(); 827c5b2abe0SLewanczyk, Dawid return; 828c5b2abe0SLewanczyk, Dawid } 829c5b2abe0SLewanczyk, Dawid // Parse JSON request body 830c5b2abe0SLewanczyk, Dawid nlohmann::json patch; 831*1abe55efSEd Tanous if (!json_util::processJsonFromRequest(res, req, patch)) 832*1abe55efSEd Tanous { 833c5b2abe0SLewanczyk, Dawid return; 834c5b2abe0SLewanczyk, Dawid } 835c5b2abe0SLewanczyk, Dawid // Find key with new led value 836c5b2abe0SLewanczyk, Dawid const std::string &name = params[0]; 837c5b2abe0SLewanczyk, Dawid const std::string *reqLedState = nullptr; 838c5b2abe0SLewanczyk, Dawid json_util::Result r = json_util::getString( 839c5b2abe0SLewanczyk, Dawid "IndicatorLED", patch, reqLedState, 840c5b2abe0SLewanczyk, Dawid static_cast<int>(json_util::MessageSetting::TYPE_ERROR) | 841c5b2abe0SLewanczyk, Dawid static_cast<int>(json_util::MessageSetting::MISSING), 84255c7b7a2SEd Tanous res.jsonValue, std::string("/" + name + "/IndicatorLED")); 843*1abe55efSEd Tanous if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr)) 844*1abe55efSEd Tanous { 845c5b2abe0SLewanczyk, Dawid res.result(boost::beast::http::status::bad_request); 846c5b2abe0SLewanczyk, Dawid res.end(); 847c5b2abe0SLewanczyk, Dawid return; 848c5b2abe0SLewanczyk, Dawid } 849c5b2abe0SLewanczyk, Dawid // Verify key value 850c5b2abe0SLewanczyk, Dawid std::string dbusLedState; 851*1abe55efSEd Tanous for (const auto &p : 852*1abe55efSEd Tanous boost::container::flat_map<const char *, const char *>{ 853*1abe55efSEd Tanous {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}}) 854*1abe55efSEd Tanous { 855*1abe55efSEd Tanous if (*reqLedState == p.second) 856*1abe55efSEd Tanous { 857c5b2abe0SLewanczyk, Dawid dbusLedState = p.first; 858c5b2abe0SLewanczyk, Dawid } 859c5b2abe0SLewanczyk, Dawid } 860c5b2abe0SLewanczyk, Dawid 861c5b2abe0SLewanczyk, Dawid // Update led status 862c5b2abe0SLewanczyk, Dawid auto asyncResp = std::make_shared<SystemAsyncResp>(res); 86355c7b7a2SEd Tanous res.jsonValue = Node::json; 86455c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; 865c5b2abe0SLewanczyk, Dawid 866c5b2abe0SLewanczyk, Dawid provider.getHostState(asyncResp); 867c5b2abe0SLewanczyk, Dawid provider.getComputerSystem(asyncResp, name); 868c5b2abe0SLewanczyk, Dawid 869*1abe55efSEd Tanous if (dbusLedState.empty()) 870*1abe55efSEd Tanous { 871c5b2abe0SLewanczyk, Dawid messages::addMessageToJsonRoot( 87255c7b7a2SEd Tanous res.jsonValue, 873c5b2abe0SLewanczyk, Dawid messages::propertyValueNotInList(*reqLedState, "IndicatorLED")); 874*1abe55efSEd Tanous } 875*1abe55efSEd Tanous else 876*1abe55efSEd Tanous { 877c5b2abe0SLewanczyk, Dawid // Update led group 87855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led group."; 87955c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 880c5b2abe0SLewanczyk, Dawid [&, asyncResp{std::move(asyncResp)}]( 881c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 882*1abe55efSEd Tanous if (ec) 883*1abe55efSEd Tanous { 88455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 885c5b2abe0SLewanczyk, Dawid asyncResp->setErrorStatus(); 886c5b2abe0SLewanczyk, Dawid return; 887c5b2abe0SLewanczyk, Dawid } 88855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led group update done."; 889c5b2abe0SLewanczyk, Dawid }, 890c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.GroupManager", 891c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/groups/enclosure_identify", 892c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 893c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Group", "Asserted", 894c5b2abe0SLewanczyk, Dawid sdbusplus::message::variant<bool>( 895c5b2abe0SLewanczyk, Dawid (dbusLedState == "Off" ? false : true))); 896c5b2abe0SLewanczyk, Dawid // Update identify led status 89755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection."; 89855c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 899c5b2abe0SLewanczyk, Dawid [&, asyncResp{std::move(asyncResp)}]( 900c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec) { 901*1abe55efSEd Tanous if (ec) 902*1abe55efSEd Tanous { 90355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 904c5b2abe0SLewanczyk, Dawid asyncResp->setErrorStatus(); 905c5b2abe0SLewanczyk, Dawid return; 906c5b2abe0SLewanczyk, Dawid } 90755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Led state update done."; 90855c7b7a2SEd Tanous res.jsonValue["IndicatorLED"] = *reqLedState; 909c5b2abe0SLewanczyk, Dawid }, 910c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.LED.Controller.identify", 911c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/led/physical/identify", 912c5b2abe0SLewanczyk, Dawid "org.freedesktop.DBus.Properties", "Set", 913c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical", "State", 914c5b2abe0SLewanczyk, Dawid sdbusplus::message::variant<std::string>( 915c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.Led.Physical.Action." + dbusLedState)); 916c5b2abe0SLewanczyk, Dawid } 917c5b2abe0SLewanczyk, Dawid } 918c5b2abe0SLewanczyk, Dawid }; 919c5b2abe0SLewanczyk, Dawid } // namespace redfish 920