1e37f8451SRapkiewicz, Pawel /* 2e37f8451SRapkiewicz, Pawel // Copyright (c) 2018 Intel Corporation 3e37f8451SRapkiewicz, Pawel // 4e37f8451SRapkiewicz, Pawel // Licensed under the Apache License, Version 2.0 (the "License"); 5e37f8451SRapkiewicz, Pawel // you may not use this file except in compliance with the License. 6e37f8451SRapkiewicz, Pawel // You may obtain a copy of the License at 7e37f8451SRapkiewicz, Pawel // 8e37f8451SRapkiewicz, Pawel // http://www.apache.org/licenses/LICENSE-2.0 9e37f8451SRapkiewicz, Pawel // 10e37f8451SRapkiewicz, Pawel // Unless required by applicable law or agreed to in writing, software 11e37f8451SRapkiewicz, Pawel // distributed under the License is distributed on an "AS IS" BASIS, 12e37f8451SRapkiewicz, Pawel // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e37f8451SRapkiewicz, Pawel // See the License for the specific language governing permissions and 14e37f8451SRapkiewicz, Pawel // limitations under the License. 15e37f8451SRapkiewicz, Pawel */ 16e37f8451SRapkiewicz, Pawel #pragma once 17e37f8451SRapkiewicz, Pawel 1813451e39SWilly Tu #include "bmcweb_config.h" 1913451e39SWilly Tu 203ccb3adbSEd Tanous #include "app.hpp" 217a1dbc48SGeorge Liu #include "dbus_utility.hpp" 22b49ac873SJames Feist #include "health.hpp" 231c8fba97SJames Feist #include "led.hpp" 243ccb3adbSEd Tanous #include "query.hpp" 253ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 263ccb3adbSEd Tanous #include "utils/collection.hpp" 273ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 28cf7eba09SNan Zhou #include "utils/json_utils.hpp" 291abe55efSEd Tanous 30e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 31ef4c65b7SEd Tanous #include <boost/url/format.hpp> 321e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 33fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp> 3486d89ed7SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 351214b7e7SGunnar Mills 367a1dbc48SGeorge Liu #include <array> 377a1dbc48SGeorge Liu #include <string_view> 387a1dbc48SGeorge Liu 391abe55efSEd Tanous namespace redfish 401abe55efSEd Tanous { 41e37f8451SRapkiewicz, Pawel 42e37f8451SRapkiewicz, Pawel /** 43beeca0aeSGunnar Mills * @brief Retrieves chassis state properties over dbus 44beeca0aeSGunnar Mills * 45*ac106bf6SEd Tanous * @param[in] asyncResp - Shared pointer for completing asynchronous calls. 46beeca0aeSGunnar Mills * 47beeca0aeSGunnar Mills * @return None. 48beeca0aeSGunnar Mills */ 49*ac106bf6SEd Tanous inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> asyncResp) 50beeca0aeSGunnar Mills { 511e1e598dSJonathan Doman // crow::connections::systemBus->async_method_call( 521e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 531e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 541e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 551e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "CurrentPowerState", 56*ac106bf6SEd Tanous [asyncResp{std::move(asyncResp)}](const boost::system::error_code& ec, 571e1e598dSJonathan Doman const std::string& chassisState) { 58beeca0aeSGunnar Mills if (ec) 59beeca0aeSGunnar Mills { 60a6e5e0abSCarson Labrado if (ec == boost::system::errc::host_unreachable) 61a6e5e0abSCarson Labrado { 62a6e5e0abSCarson Labrado // Service not available, no error, just don't return 63a6e5e0abSCarson Labrado // chassis state info 64a6e5e0abSCarson Labrado BMCWEB_LOG_DEBUG << "Service not available " << ec; 65a6e5e0abSCarson Labrado return; 66a6e5e0abSCarson Labrado } 67*ac106bf6SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 68*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 69beeca0aeSGunnar Mills return; 70beeca0aeSGunnar Mills } 71beeca0aeSGunnar Mills 721e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Chassis state: " << chassisState; 73beeca0aeSGunnar Mills // Verify Chassis State 74002d39b4SEd Tanous if (chassisState == "xyz.openbmc_project.State.Chassis.PowerState.On") 75beeca0aeSGunnar Mills { 76*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 77*ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 78beeca0aeSGunnar Mills } 791e1e598dSJonathan Doman else if (chassisState == 80beeca0aeSGunnar Mills "xyz.openbmc_project.State.Chassis.PowerState.Off") 81beeca0aeSGunnar Mills { 82*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 83*ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "StandbyOffline"; 84beeca0aeSGunnar Mills } 851e1e598dSJonathan Doman }); 86beeca0aeSGunnar Mills } 87beeca0aeSGunnar Mills 88*ac106bf6SEd Tanous inline void getIntrusionByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 89c181942fSQiang XU const std::string& service, 90c181942fSQiang XU const std::string& objPath) 91c181942fSQiang XU { 92c181942fSQiang XU BMCWEB_LOG_DEBUG << "Get intrusion status by service \n"; 93c181942fSQiang XU 941e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 951e1e598dSJonathan Doman *crow::connections::systemBus, service, objPath, 961e1e598dSJonathan Doman "xyz.openbmc_project.Chassis.Intrusion", "Status", 97*ac106bf6SEd Tanous [asyncResp{std::move(asyncResp)}](const boost::system::error_code& ec, 981e1e598dSJonathan Doman const std::string& value) { 99c181942fSQiang XU if (ec) 100c181942fSQiang XU { 1014e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 102c181942fSQiang XU // mandatory property 103c181942fSQiang XU BMCWEB_LOG_ERROR << "DBUS response error " << ec << "\n"; 104c181942fSQiang XU return; 105c181942fSQiang XU } 106c181942fSQiang XU 107*ac106bf6SEd Tanous asyncResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensorNumber"] = 108*ac106bf6SEd Tanous 1; 109*ac106bf6SEd Tanous asyncResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensor"] = value; 1101e1e598dSJonathan Doman }); 111c181942fSQiang XU } 112c181942fSQiang XU 113c181942fSQiang XU /** 114c181942fSQiang XU * Retrieves physical security properties over dbus 115c181942fSQiang XU */ 116*ac106bf6SEd Tanous inline void 117*ac106bf6SEd Tanous getPhysicalSecurityData(std::shared_ptr<bmcweb::AsyncResp> asyncResp) 118c181942fSQiang XU { 119e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 120e99073f5SGeorge Liu "xyz.openbmc_project.Chassis.Intrusion"}; 121e99073f5SGeorge Liu dbus::utility::getSubTree( 122e99073f5SGeorge Liu "/xyz/openbmc_project/Intrusion", 1, interfaces, 123*ac106bf6SEd Tanous [asyncResp{std::move(asyncResp)}]( 124e99073f5SGeorge Liu const boost::system::error_code& ec, 125b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 126c181942fSQiang XU if (ec) 127c181942fSQiang XU { 1284e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 129c181942fSQiang XU // mandatory property 130002d39b4SEd Tanous BMCWEB_LOG_INFO << "DBUS error: no matched iface " << ec << "\n"; 131c181942fSQiang XU return; 132c181942fSQiang XU } 133c181942fSQiang XU // Iterate over all retrieved ObjectPaths. 134c181942fSQiang XU for (const auto& object : subtree) 135c181942fSQiang XU { 136840a9ffcSPatrick Williams if (!object.second.empty()) 137c181942fSQiang XU { 138840a9ffcSPatrick Williams const auto service = object.second.front(); 139*ac106bf6SEd Tanous getIntrusionByService(asyncResp, service.first, object.first); 140c181942fSQiang XU return; 141c181942fSQiang XU } 142c181942fSQiang XU } 143e99073f5SGeorge Liu }); 144c181942fSQiang XU } 145c181942fSQiang XU 146cf7eba09SNan Zhou inline void handleChassisCollectionGet( 147cf7eba09SNan Zhou App& app, const crow::Request& req, 148cf7eba09SNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1491abe55efSEd Tanous { 1503ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 15145ca1b86SEd Tanous { 15245ca1b86SEd Tanous return; 15345ca1b86SEd Tanous } 1548d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 1558d1b46d7Szhanghch05 "#ChassisCollection.ChassisCollection"; 1568d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis"; 1578d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Chassis Collection"; 158e37f8451SRapkiewicz, Pawel 1597a1dbc48SGeorge Liu constexpr std::array<std::string_view, 2> interfaces{ 1607a1dbc48SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board", 1617a1dbc48SGeorge Liu "xyz.openbmc_project.Inventory.Item.Chassis"}; 16202f6ff19SGunnar Mills collection_util::getCollectionMembers( 1637a1dbc48SGeorge Liu asyncResp, boost::urls::url("/redfish/v1/Chassis"), interfaces); 164cf7eba09SNan Zhou } 165cf7eba09SNan Zhou 166cf7eba09SNan Zhou /** 167cf7eba09SNan Zhou * ChassisCollection derived class for delivering Chassis Collection Schema 168cf7eba09SNan Zhou * Functions triggers appropriate requests on DBus 169cf7eba09SNan Zhou */ 170cf7eba09SNan Zhou inline void requestRoutesChassisCollection(App& app) 171cf7eba09SNan Zhou { 172cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/") 173cf7eba09SNan Zhou .privileges(redfish::privileges::getChassisCollection) 174cf7eba09SNan Zhou .methods(boost::beast::http::verb::get)( 175cf7eba09SNan Zhou std::bind_front(handleChassisCollectionGet, std::ref(app))); 17662d5e2e4SEd Tanous } 177e37f8451SRapkiewicz, Pawel 178308f70c7SWilly Tu inline void 179308f70c7SWilly Tu getChassisLocationCode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 180308f70c7SWilly Tu const std::string& connectionName, 181308f70c7SWilly Tu const std::string& path) 182308f70c7SWilly Tu { 1831e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 1841e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 1851e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode", 1865e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec, 1871e1e598dSJonathan Doman const std::string& property) { 188308f70c7SWilly Tu if (ec) 189308f70c7SWilly Tu { 19051dab2a7SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error for Location"; 191308f70c7SWilly Tu messages::internalError(asyncResp->res); 192308f70c7SWilly Tu return; 193308f70c7SWilly Tu } 194308f70c7SWilly Tu 195002d39b4SEd Tanous asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 1961e1e598dSJonathan Doman property; 1971e1e598dSJonathan Doman }); 198308f70c7SWilly Tu } 199308f70c7SWilly Tu 200308f70c7SWilly Tu inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 201308f70c7SWilly Tu const std::string& connectionName, 202308f70c7SWilly Tu const std::string& path) 203308f70c7SWilly Tu { 2041e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2051e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 2061e1e598dSJonathan Doman "xyz.openbmc_project.Common.UUID", "UUID", 2075e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec, 2081e1e598dSJonathan Doman const std::string& chassisUUID) { 209308f70c7SWilly Tu if (ec) 210308f70c7SWilly Tu { 21151dab2a7SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error for UUID"; 212308f70c7SWilly Tu messages::internalError(asyncResp->res); 213308f70c7SWilly Tu return; 214308f70c7SWilly Tu } 2151e1e598dSJonathan Doman asyncResp->res.jsonValue["UUID"] = chassisUUID; 2161e1e598dSJonathan Doman }); 217308f70c7SWilly Tu } 218308f70c7SWilly Tu 219cf7eba09SNan Zhou inline void 220cf7eba09SNan Zhou handleChassisGet(App& app, const crow::Request& req, 22145ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 222cf7eba09SNan Zhou const std::string& chassisId) 223cf7eba09SNan Zhou { 2243ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 22545ca1b86SEd Tanous { 22645ca1b86SEd Tanous return; 22745ca1b86SEd Tanous } 228e99073f5SGeorge Liu constexpr std::array<std::string_view, 2> interfaces = { 229734bfe90SGunnar Mills "xyz.openbmc_project.Inventory.Item.Board", 230adc4f0dbSShawn McCarney "xyz.openbmc_project.Inventory.Item.Chassis"}; 231734bfe90SGunnar Mills 232e99073f5SGeorge Liu dbus::utility::getSubTree( 233e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 23462d5e2e4SEd Tanous [asyncResp, chassisId(std::string(chassisId))]( 235e99073f5SGeorge Liu const boost::system::error_code& ec, 236b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 23762d5e2e4SEd Tanous if (ec) 2381abe55efSEd Tanous { 23951dab2a7SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 240f12894f8SJason M. Bills messages::internalError(asyncResp->res); 241daf36e2eSEd Tanous return; 242daf36e2eSEd Tanous } 243daf36e2eSEd Tanous // Iterate over all retrieved ObjectPaths. 244cf7eba09SNan Zhou for (const std::pair< 245cf7eba09SNan Zhou std::string, 246cf7eba09SNan Zhou std::vector<std::pair<std::string, std::vector<std::string>>>>& 2471214b7e7SGunnar Mills object : subtree) 2481abe55efSEd Tanous { 249daf36e2eSEd Tanous const std::string& path = object.first; 250cf7eba09SNan Zhou const std::vector<std::pair<std::string, std::vector<std::string>>>& 2511214b7e7SGunnar Mills connectionNames = object.second; 2527e860f15SJohn Edward Broadbent 253997093ebSGeorge Liu sdbusplus::message::object_path objPath(path); 254997093ebSGeorge Liu if (objPath.filename() != chassisId) 2551abe55efSEd Tanous { 256daf36e2eSEd Tanous continue; 257daf36e2eSEd Tanous } 25826f03899SShawn McCarney 259002d39b4SEd Tanous auto health = std::make_shared<HealthPopulate>(asyncResp); 260b49ac873SJames Feist 26113451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 26213451e39SWilly Tu { 2636c3e9451SGeorge Liu dbus::utility::getAssociationEndPoints( 2646c3e9451SGeorge Liu path + "/all_sensors", 2655e7e2dc5SEd Tanous [health](const boost::system::error_code& ec2, 2666c3e9451SGeorge Liu const dbus::utility::MapperEndPoints& resp) { 26723a21a1cSEd Tanous if (ec2) 268b49ac873SJames Feist { 269b49ac873SJames Feist return; // no sensors = no failures 270b49ac873SJames Feist } 2711e1e598dSJonathan Doman health->inventory = resp; 2721e1e598dSJonathan Doman }); 273b49ac873SJames Feist 274b49ac873SJames Feist health->populate(); 27513451e39SWilly Tu } 276b49ac873SJames Feist 27726f6976fSEd Tanous if (connectionNames.empty()) 2781abe55efSEd Tanous { 2791c8fba97SJames Feist BMCWEB_LOG_ERROR << "Got 0 Connection names"; 280e0d918bcSEd Tanous continue; 281daf36e2eSEd Tanous } 282e0d918bcSEd Tanous 28349c53ac9SJohnathan Mantey asyncResp->res.jsonValue["@odata.type"] = 284523d4868SLogananth Sundararaj "#Chassis.v1_22_0.Chassis"; 28549c53ac9SJohnathan Mantey asyncResp->res.jsonValue["@odata.id"] = 286ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}", chassisId); 28749c53ac9SJohnathan Mantey asyncResp->res.jsonValue["Name"] = "Chassis Collection"; 28849c53ac9SJohnathan Mantey asyncResp->res.jsonValue["ChassisType"] = "RackMount"; 289cf7eba09SNan Zhou asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]["target"] = 290ef4c65b7SEd Tanous boost::urls::format( 291ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/Actions/Chassis.Reset", chassisId); 2921476687dSEd Tanous asyncResp->res 293cf7eba09SNan Zhou .jsonValue["Actions"]["#Chassis.Reset"]["@Redfish.ActionInfo"] = 294ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/ResetActionInfo", 295ef4c65b7SEd Tanous chassisId); 2961476687dSEd Tanous asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] = 297ef4c65b7SEd Tanous "/redfish/v1/Systems/system/PCIeDevices"; 29849c53ac9SJohnathan Mantey 2996c3e9451SGeorge Liu dbus::utility::getAssociationEndPoints( 3006c3e9451SGeorge Liu path + "/drive", 3016c3e9451SGeorge Liu [asyncResp, 3026c3e9451SGeorge Liu chassisId](const boost::system::error_code& ec3, 3036c3e9451SGeorge Liu const dbus::utility::MapperEndPoints& resp) { 30492903bd4SJohn Edward Broadbent if (ec3 || resp.empty()) 30592903bd4SJohn Edward Broadbent { 30692903bd4SJohn Edward Broadbent return; // no drives = no failures 30792903bd4SJohn Edward Broadbent } 30892903bd4SJohn Edward Broadbent 30992903bd4SJohn Edward Broadbent nlohmann::json reference; 310ef4c65b7SEd Tanous reference["@odata.id"] = boost::urls::format( 311ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/Drives", chassisId); 31292903bd4SJohn Edward Broadbent asyncResp->res.jsonValue["Drives"] = std::move(reference); 31392903bd4SJohn Edward Broadbent }); 31492903bd4SJohn Edward Broadbent 315002d39b4SEd Tanous const std::string& connectionName = connectionNames[0].first; 3161c8fba97SJames Feist 31723a21a1cSEd Tanous const std::vector<std::string>& interfaces2 = 3181c8fba97SJames Feist connectionNames[0].second; 3191c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 3201c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 3210fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 3221c8fba97SJames Feist 323476b9cc5STejas Patil const std::string assetTagInterface = 3240fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag"; 325523d4868SLogananth Sundararaj const std::string replaceableInterface = 326523d4868SLogananth Sundararaj "xyz.openbmc_project.Inventory.Decorator.Replaceable"; 327523d4868SLogananth Sundararaj for (const auto& interface : interfaces2) 328523d4868SLogananth Sundararaj { 329523d4868SLogananth Sundararaj if (interface == assetTagInterface) 330476b9cc5STejas Patil { 3311e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 332002d39b4SEd Tanous *crow::connections::systemBus, connectionName, path, 333002d39b4SEd Tanous assetTagInterface, "AssetTag", 334523d4868SLogananth Sundararaj [asyncResp, 335523d4868SLogananth Sundararaj chassisId](const boost::system::error_code& ec2, 3361e1e598dSJonathan Doman const std::string& property) { 3378a592810SEd Tanous if (ec2) 338476b9cc5STejas Patil { 339523d4868SLogananth Sundararaj BMCWEB_LOG_ERROR 340523d4868SLogananth Sundararaj << "DBus response error for AssetTag: " << ec2; 341476b9cc5STejas Patil messages::internalError(asyncResp->res); 342476b9cc5STejas Patil return; 343476b9cc5STejas Patil } 344002d39b4SEd Tanous asyncResp->res.jsonValue["AssetTag"] = property; 3451e1e598dSJonathan Doman }); 346476b9cc5STejas Patil } 347523d4868SLogananth Sundararaj else if (interface == replaceableInterface) 348523d4868SLogananth Sundararaj { 349523d4868SLogananth Sundararaj sdbusplus::asio::getProperty<bool>( 350523d4868SLogananth Sundararaj *crow::connections::systemBus, connectionName, path, 351523d4868SLogananth Sundararaj replaceableInterface, "HotPluggable", 352523d4868SLogananth Sundararaj [asyncResp, 353523d4868SLogananth Sundararaj chassisId](const boost::system::error_code& ec2, 354523d4868SLogananth Sundararaj const bool property) { 355523d4868SLogananth Sundararaj if (ec2) 356523d4868SLogananth Sundararaj { 357523d4868SLogananth Sundararaj BMCWEB_LOG_ERROR 358523d4868SLogananth Sundararaj << "DBus response error for HotPluggable: " 359523d4868SLogananth Sundararaj << ec2; 360523d4868SLogananth Sundararaj messages::internalError(asyncResp->res); 361523d4868SLogananth Sundararaj return; 362523d4868SLogananth Sundararaj } 363523d4868SLogananth Sundararaj asyncResp->res.jsonValue["HotPluggable"] = property; 364523d4868SLogananth Sundararaj }); 365523d4868SLogananth Sundararaj } 366523d4868SLogananth Sundararaj } 367476b9cc5STejas Patil 3681c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 3691c8fba97SJames Feist { 370002d39b4SEd Tanous if (std::find(interfaces2.begin(), interfaces2.end(), 37123a21a1cSEd Tanous interface) != interfaces2.end()) 3721c8fba97SJames Feist { 3731c8fba97SJames Feist getIndicatorLedState(asyncResp); 3749f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 3751c8fba97SJames Feist break; 3761c8fba97SJames Feist } 3771c8fba97SJames Feist } 3781c8fba97SJames Feist 37986d89ed7SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 38086d89ed7SKrzysztof Grobelny *crow::connections::systemBus, connectionName, path, 38186d89ed7SKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 38262d5e2e4SEd Tanous [asyncResp, chassisId(std::string(chassisId))]( 3835e7e2dc5SEd Tanous const boost::system::error_code& /*ec2*/, 384cf7eba09SNan Zhou const dbus::utility::DBusPropertiesMap& propertiesList) { 38586d89ed7SKrzysztof Grobelny const std::string* partNumber = nullptr; 38686d89ed7SKrzysztof Grobelny const std::string* serialNumber = nullptr; 38786d89ed7SKrzysztof Grobelny const std::string* manufacturer = nullptr; 38886d89ed7SKrzysztof Grobelny const std::string* model = nullptr; 38986d89ed7SKrzysztof Grobelny const std::string* sparePartNumber = nullptr; 39086d89ed7SKrzysztof Grobelny 39186d89ed7SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 39286d89ed7SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), propertiesList, 39386d89ed7SKrzysztof Grobelny "PartNumber", partNumber, "SerialNumber", serialNumber, 39486d89ed7SKrzysztof Grobelny "Manufacturer", manufacturer, "Model", model, 39586d89ed7SKrzysztof Grobelny "SparePartNumber", sparePartNumber); 39686d89ed7SKrzysztof Grobelny 39786d89ed7SKrzysztof Grobelny if (!success) 3981abe55efSEd Tanous { 399002d39b4SEd Tanous messages::internalError(asyncResp->res); 400caa11f7aSAlpana Kumari return; 401daf36e2eSEd Tanous } 40286d89ed7SKrzysztof Grobelny 40386d89ed7SKrzysztof Grobelny if (partNumber != nullptr) 40486d89ed7SKrzysztof Grobelny { 40586d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["PartNumber"] = *partNumber; 40686d89ed7SKrzysztof Grobelny } 40786d89ed7SKrzysztof Grobelny 40886d89ed7SKrzysztof Grobelny if (serialNumber != nullptr) 40986d89ed7SKrzysztof Grobelny { 41086d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 41186d89ed7SKrzysztof Grobelny } 41286d89ed7SKrzysztof Grobelny 41386d89ed7SKrzysztof Grobelny if (manufacturer != nullptr) 41486d89ed7SKrzysztof Grobelny { 41586d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["Manufacturer"] = *manufacturer; 41686d89ed7SKrzysztof Grobelny } 41786d89ed7SKrzysztof Grobelny 41886d89ed7SKrzysztof Grobelny if (model != nullptr) 41986d89ed7SKrzysztof Grobelny { 42086d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["Model"] = *model; 42186d89ed7SKrzysztof Grobelny } 42286d89ed7SKrzysztof Grobelny 423caa11f7aSAlpana Kumari // SparePartNumber is optional on D-Bus 424caa11f7aSAlpana Kumari // so skip if it is empty 42586d89ed7SKrzysztof Grobelny if (sparePartNumber != nullptr && !sparePartNumber->empty()) 426caa11f7aSAlpana Kumari { 42786d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["SparePartNumber"] = 42886d89ed7SKrzysztof Grobelny *sparePartNumber; 429caa11f7aSAlpana Kumari } 43086d89ed7SKrzysztof Grobelny 43162d5e2e4SEd Tanous asyncResp->res.jsonValue["Name"] = chassisId; 43262d5e2e4SEd Tanous asyncResp->res.jsonValue["Id"] = chassisId; 4330256b694Szhanghch05 #ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL 434002d39b4SEd Tanous asyncResp->res.jsonValue["Thermal"]["@odata.id"] = 435ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/Thermal", 436ef4c65b7SEd Tanous chassisId); 4372474adfaSEd Tanous // Power object 4381476687dSEd Tanous asyncResp->res.jsonValue["Power"]["@odata.id"] = 439ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/Power", 440ef4c65b7SEd Tanous chassisId); 4410256b694Szhanghch05 #endif 4422973963eSXiaochao Ma #ifdef BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM 4432973963eSXiaochao Ma asyncResp->res.jsonValue["ThermalSubsystem"]["@odata.id"] = 444ef4c65b7SEd Tanous boost::urls::format( 445ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/ThermalSubsystem", chassisId); 44677b36437SChicago Duan asyncResp->res.jsonValue["PowerSubsystem"]["@odata.id"] = 447ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/PowerSubsystem", 448ef4c65b7SEd Tanous chassisId); 4494ca3ec3cSAlbert Zhang asyncResp->res.jsonValue["EnvironmentMetrics"]["@odata.id"] = 450ef4c65b7SEd Tanous boost::urls::format( 451ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/EnvironmentMetrics", chassisId); 4522973963eSXiaochao Ma #endif 45395a3ecadSAnthony Wilson // SensorCollection 454002d39b4SEd Tanous asyncResp->res.jsonValue["Sensors"]["@odata.id"] = 455ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/Sensors", 456ef4c65b7SEd Tanous chassisId); 457002d39b4SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 4581476687dSEd Tanous 4591476687dSEd Tanous nlohmann::json::array_t computerSystems; 4601476687dSEd Tanous nlohmann::json::object_t system; 461002d39b4SEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 462ad539545SPatrick Williams computerSystems.emplace_back(std::move(system)); 463002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ComputerSystems"] = 4641476687dSEd Tanous std::move(computerSystems); 4651476687dSEd Tanous 4661476687dSEd Tanous nlohmann::json::array_t managedBy; 4671476687dSEd Tanous nlohmann::json::object_t manager; 468002d39b4SEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 469ad539545SPatrick Williams managedBy.emplace_back(std::move(manager)); 4707e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Links"]["ManagedBy"] = 4711476687dSEd Tanous std::move(managedBy); 472beeca0aeSGunnar Mills getChassisState(asyncResp); 47386d89ed7SKrzysztof Grobelny }); 4742c37b4b0SSharad Yadav 475308f70c7SWilly Tu for (const auto& interface : interfaces2) 4762c37b4b0SSharad Yadav { 477308f70c7SWilly Tu if (interface == "xyz.openbmc_project.Common.UUID") 4782c37b4b0SSharad Yadav { 479308f70c7SWilly Tu getChassisUUID(asyncResp, connectionName, path); 4802c37b4b0SSharad Yadav } 481cf7eba09SNan Zhou else if (interface == 4820fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.LocationCode") 4832c37b4b0SSharad Yadav { 484002d39b4SEd Tanous getChassisLocationCode(asyncResp, connectionName, path); 4852c37b4b0SSharad Yadav } 4862c37b4b0SSharad Yadav } 4872c37b4b0SSharad Yadav 488daf36e2eSEd Tanous return; 489daf36e2eSEd Tanous } 490e0d918bcSEd Tanous 491daf36e2eSEd Tanous // Couldn't find an object with that name. return an error 492d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); 493e99073f5SGeorge Liu }); 494c181942fSQiang XU 495c181942fSQiang XU getPhysicalSecurityData(asyncResp); 496cf7eba09SNan Zhou } 4971c8fba97SJames Feist 498cf7eba09SNan Zhou inline void 499cf7eba09SNan Zhou handleChassisPatch(App& app, const crow::Request& req, 5007e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 501cf7eba09SNan Zhou const std::string& param) 502cf7eba09SNan Zhou { 5033ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 50445ca1b86SEd Tanous { 50545ca1b86SEd Tanous return; 50645ca1b86SEd Tanous } 5079f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 5081c8fba97SJames Feist std::optional<std::string> indicatorLed; 5091c8fba97SJames Feist 5107e860f15SJohn Edward Broadbent if (param.empty()) 5111c8fba97SJames Feist { 5121c8fba97SJames Feist return; 5131c8fba97SJames Feist } 5141c8fba97SJames Feist 51515ed6780SWilly Tu if (!json_util::readJsonPatch( 5167e860f15SJohn Edward Broadbent req, asyncResp->res, "LocationIndicatorActive", 5177e860f15SJohn Edward Broadbent locationIndicatorActive, "IndicatorLED", indicatorLed)) 5181c8fba97SJames Feist { 5191c8fba97SJames Feist return; 5201c8fba97SJames Feist } 5211c8fba97SJames Feist 5229f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 5239f8bfa7cSGunnar Mills if (!locationIndicatorActive && !indicatorLed) 5241c8fba97SJames Feist { 5251c8fba97SJames Feist return; // delete this when we support more patch properties 5261c8fba97SJames Feist } 527d6aa0093SGunnar Mills if (indicatorLed) 528d6aa0093SGunnar Mills { 5297e860f15SJohn Edward Broadbent asyncResp->res.addHeader( 5307e860f15SJohn Edward Broadbent boost::beast::http::field::warning, 5310fda0f12SGeorge Liu "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\""); 532d6aa0093SGunnar Mills } 5331c8fba97SJames Feist 534e99073f5SGeorge Liu constexpr std::array<std::string_view, 2> interfaces = { 5351c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Board", 5361c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Chassis"}; 5371c8fba97SJames Feist 5387e860f15SJohn Edward Broadbent const std::string& chassisId = param; 5391c8fba97SJames Feist 540e99073f5SGeorge Liu dbus::utility::getSubTree( 541e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 542cf7eba09SNan Zhou [asyncResp, chassisId, locationIndicatorActive, 5435e7e2dc5SEd Tanous indicatorLed](const boost::system::error_code& ec, 544b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 5451c8fba97SJames Feist if (ec) 5461c8fba97SJames Feist { 54751dab2a7SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 5481c8fba97SJames Feist messages::internalError(asyncResp->res); 5491c8fba97SJames Feist return; 5501c8fba97SJames Feist } 5511c8fba97SJames Feist 5521c8fba97SJames Feist // Iterate over all retrieved ObjectPaths. 553cf7eba09SNan Zhou for (const std::pair< 554cf7eba09SNan Zhou std::string, 555cf7eba09SNan Zhou std::vector<std::pair<std::string, std::vector<std::string>>>>& 5561214b7e7SGunnar Mills object : subtree) 5571c8fba97SJames Feist { 5581c8fba97SJames Feist const std::string& path = object.first; 559cf7eba09SNan Zhou const std::vector<std::pair<std::string, std::vector<std::string>>>& 5601214b7e7SGunnar Mills connectionNames = object.second; 5611c8fba97SJames Feist 562997093ebSGeorge Liu sdbusplus::message::object_path objPath(path); 563997093ebSGeorge Liu if (objPath.filename() != chassisId) 5641c8fba97SJames Feist { 5651c8fba97SJames Feist continue; 5661c8fba97SJames Feist } 5671c8fba97SJames Feist 56826f6976fSEd Tanous if (connectionNames.empty()) 5691c8fba97SJames Feist { 5701c8fba97SJames Feist BMCWEB_LOG_ERROR << "Got 0 Connection names"; 5711c8fba97SJames Feist continue; 5721c8fba97SJames Feist } 5731c8fba97SJames Feist 57423a21a1cSEd Tanous const std::vector<std::string>& interfaces3 = 5751c8fba97SJames Feist connectionNames[0].second; 5761c8fba97SJames Feist 5771c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 5781c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 5790fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 5801c8fba97SJames Feist bool indicatorChassis = false; 5811c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 5821c8fba97SJames Feist { 583002d39b4SEd Tanous if (std::find(interfaces3.begin(), interfaces3.end(), 58423a21a1cSEd Tanous interface) != interfaces3.end()) 5851c8fba97SJames Feist { 5861c8fba97SJames Feist indicatorChassis = true; 5871c8fba97SJames Feist break; 5881c8fba97SJames Feist } 5891c8fba97SJames Feist } 5909f8bfa7cSGunnar Mills if (locationIndicatorActive) 5919f8bfa7cSGunnar Mills { 5929f8bfa7cSGunnar Mills if (indicatorChassis) 5939f8bfa7cSGunnar Mills { 594002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, 595002d39b4SEd Tanous *locationIndicatorActive); 5969f8bfa7cSGunnar Mills } 5979f8bfa7cSGunnar Mills else 5989f8bfa7cSGunnar Mills { 599002d39b4SEd Tanous messages::propertyUnknown(asyncResp->res, 600002d39b4SEd Tanous "LocationIndicatorActive"); 6019f8bfa7cSGunnar Mills } 6029f8bfa7cSGunnar Mills } 6039f8bfa7cSGunnar Mills if (indicatorLed) 6049f8bfa7cSGunnar Mills { 6051c8fba97SJames Feist if (indicatorChassis) 6061c8fba97SJames Feist { 607f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 6081c8fba97SJames Feist } 6091c8fba97SJames Feist else 6101c8fba97SJames Feist { 611cf7eba09SNan Zhou messages::propertyUnknown(asyncResp->res, "IndicatorLED"); 6121c8fba97SJames Feist } 6131c8fba97SJames Feist } 6141c8fba97SJames Feist return; 6151c8fba97SJames Feist } 6161c8fba97SJames Feist 617d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); 618e99073f5SGeorge Liu }); 619cf7eba09SNan Zhou } 620cf7eba09SNan Zhou 621cf7eba09SNan Zhou /** 622cf7eba09SNan Zhou * Chassis override class for delivering Chassis Schema 623cf7eba09SNan Zhou * Functions triggers appropriate requests on DBus 624cf7eba09SNan Zhou */ 625cf7eba09SNan Zhou inline void requestRoutesChassis(App& app) 626cf7eba09SNan Zhou { 627cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 628cf7eba09SNan Zhou .privileges(redfish::privileges::getChassis) 629cf7eba09SNan Zhou .methods(boost::beast::http::verb::get)( 630cf7eba09SNan Zhou std::bind_front(handleChassisGet, std::ref(app))); 631cf7eba09SNan Zhou 632cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 633cf7eba09SNan Zhou .privileges(redfish::privileges::patchChassis) 634cf7eba09SNan Zhou .methods(boost::beast::http::verb::patch)( 635cf7eba09SNan Zhou std::bind_front(handleChassisPatch, std::ref(app))); 6361c8fba97SJames Feist } 637dd99e04bSP.K. Lee 638fc903b3dSAndrew Geissler /** 639fc903b3dSAndrew Geissler * Handle error responses from d-bus for chassis power cycles 640fc903b3dSAndrew Geissler */ 641fc903b3dSAndrew Geissler inline void handleChassisPowerCycleError(const boost::system::error_code& ec, 642fc903b3dSAndrew Geissler const sdbusplus::message_t& eMsg, 643fc903b3dSAndrew Geissler crow::Response& res) 644fc903b3dSAndrew Geissler { 645fc903b3dSAndrew Geissler if (eMsg.get_error() == nullptr) 646fc903b3dSAndrew Geissler { 647fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "D-Bus response error: " << ec; 648fc903b3dSAndrew Geissler messages::internalError(res); 649fc903b3dSAndrew Geissler return; 650fc903b3dSAndrew Geissler } 651fc903b3dSAndrew Geissler std::string_view errorMessage = eMsg.get_error()->name; 652fc903b3dSAndrew Geissler 653fc903b3dSAndrew Geissler // If operation failed due to BMC not being in Ready state, tell 654fc903b3dSAndrew Geissler // user to retry in a bit 655fc903b3dSAndrew Geissler if (errorMessage == 656fc903b3dSAndrew Geissler std::string_view("xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) 657fc903b3dSAndrew Geissler { 658fc903b3dSAndrew Geissler BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now"; 659fc903b3dSAndrew Geissler messages::serviceTemporarilyUnavailable(res, "10"); 660fc903b3dSAndrew Geissler return; 661fc903b3dSAndrew Geissler } 662fc903b3dSAndrew Geissler 663fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "Chassis Power Cycle fail " << ec 664fc903b3dSAndrew Geissler << " sdbusplus:" << errorMessage; 665fc903b3dSAndrew Geissler messages::internalError(res); 666fc903b3dSAndrew Geissler } 667fc903b3dSAndrew Geissler 6688d1b46d7Szhanghch05 inline void 6698d1b46d7Szhanghch05 doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 670dd99e04bSP.K. Lee { 6717a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 672c3b3c92aSVijay Khemka "xyz.openbmc_project.State.Chassis"}; 673c3b3c92aSVijay Khemka 674c3b3c92aSVijay Khemka // Use mapper to get subtree paths. 6757a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 6767a1dbc48SGeorge Liu "/", 0, interfaces, 677b9d36b47SEd Tanous [asyncResp]( 6787a1dbc48SGeorge Liu const boost::system::error_code& ec, 679b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreePathsResponse& chassisList) { 680c3b3c92aSVijay Khemka if (ec) 681c3b3c92aSVijay Khemka { 68251dab2a7SAndrew Geissler BMCWEB_LOG_ERROR << "[mapper] Bad D-Bus request error: " << ec; 683c3b3c92aSVijay Khemka messages::internalError(asyncResp->res); 684c3b3c92aSVijay Khemka return; 685c3b3c92aSVijay Khemka } 686c3b3c92aSVijay Khemka 687dd99e04bSP.K. Lee const char* processName = "xyz.openbmc_project.State.Chassis"; 688dd99e04bSP.K. Lee const char* interfaceName = "xyz.openbmc_project.State.Chassis"; 689dd99e04bSP.K. Lee const char* destProperty = "RequestedPowerTransition"; 690dd99e04bSP.K. Lee const std::string propertyValue = 691dd99e04bSP.K. Lee "xyz.openbmc_project.State.Chassis.Transition.PowerCycle"; 692002d39b4SEd Tanous std::string objectPath = "/xyz/openbmc_project/state/chassis_system0"; 693c3b3c92aSVijay Khemka 694c3b3c92aSVijay Khemka /* Look for system reset chassis path */ 695002d39b4SEd Tanous if ((std::find(chassisList.begin(), chassisList.end(), objectPath)) == 696002d39b4SEd Tanous chassisList.end()) 697c3b3c92aSVijay Khemka { 698c3b3c92aSVijay Khemka /* We prefer to reset the full chassis_system, but if it doesn't 699c3b3c92aSVijay Khemka * exist on some platforms, fall back to a host-only power reset 700c3b3c92aSVijay Khemka */ 701c3b3c92aSVijay Khemka objectPath = "/xyz/openbmc_project/state/chassis0"; 702c3b3c92aSVijay Khemka } 703dd99e04bSP.K. Lee 704dd99e04bSP.K. Lee crow::connections::systemBus->async_method_call( 705fc903b3dSAndrew Geissler [asyncResp](const boost::system::error_code& ec2, 706fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 707dd99e04bSP.K. Lee // Use "Set" method to set the property value. 7088a592810SEd Tanous if (ec2) 709dd99e04bSP.K. Lee { 710fc903b3dSAndrew Geissler handleChassisPowerCycleError(ec2, sdbusErrMsg, asyncResp->res); 711fc903b3dSAndrew Geissler 712dd99e04bSP.K. Lee return; 713dd99e04bSP.K. Lee } 714dd99e04bSP.K. Lee 715dd99e04bSP.K. Lee messages::success(asyncResp->res); 716dd99e04bSP.K. Lee }, 717002d39b4SEd Tanous processName, objectPath, "org.freedesktop.DBus.Properties", "Set", 718002d39b4SEd Tanous interfaceName, destProperty, 719168e20c1SEd Tanous dbus::utility::DbusVariantType{propertyValue}); 7207a1dbc48SGeorge Liu }); 721dd99e04bSP.K. Lee } 722dd99e04bSP.K. Lee 723cf7eba09SNan Zhou inline void handleChassisResetActionInfoPost( 724cf7eba09SNan Zhou App& app, const crow::Request& req, 7257e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 726cf7eba09SNan Zhou const std::string& /*chassisId*/) 727cf7eba09SNan Zhou { 7283ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 72945ca1b86SEd Tanous { 73045ca1b86SEd Tanous return; 73145ca1b86SEd Tanous } 732dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Post Chassis Reset."; 733dd99e04bSP.K. Lee 734dd99e04bSP.K. Lee std::string resetType; 735dd99e04bSP.K. Lee 736cf7eba09SNan Zhou if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 737dd99e04bSP.K. Lee { 738dd99e04bSP.K. Lee return; 739dd99e04bSP.K. Lee } 740dd99e04bSP.K. Lee 741dd99e04bSP.K. Lee if (resetType != "PowerCycle") 742dd99e04bSP.K. Lee { 743dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: " 744dd99e04bSP.K. Lee << resetType; 745002d39b4SEd Tanous messages::actionParameterNotSupported(asyncResp->res, resetType, 746002d39b4SEd Tanous "ResetType"); 747dd99e04bSP.K. Lee 748dd99e04bSP.K. Lee return; 749dd99e04bSP.K. Lee } 750dd99e04bSP.K. Lee doChassisPowerCycle(asyncResp); 751dd99e04bSP.K. Lee } 7521cb1a9e6SAppaRao Puli 7531cb1a9e6SAppaRao Puli /** 754cf7eba09SNan Zhou * ChassisResetAction class supports the POST method for the Reset 755cf7eba09SNan Zhou * action. 756cf7eba09SNan Zhou * Function handles POST method request. 757cf7eba09SNan Zhou * Analyzes POST body before sending Reset request data to D-Bus. 7581cb1a9e6SAppaRao Puli */ 759cf7eba09SNan Zhou 760cf7eba09SNan Zhou inline void requestRoutesChassisResetAction(App& app) 7611cb1a9e6SAppaRao Puli { 762cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/") 763cf7eba09SNan Zhou .privileges(redfish::privileges::postChassis) 764cf7eba09SNan Zhou .methods(boost::beast::http::verb::post)( 765cf7eba09SNan Zhou std::bind_front(handleChassisResetActionInfoPost, std::ref(app))); 766cf7eba09SNan Zhou } 767cf7eba09SNan Zhou 768cf7eba09SNan Zhou inline void handleChassisResetActionInfoGet( 769cf7eba09SNan Zhou App& app, const crow::Request& req, 7707e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 771cf7eba09SNan Zhou const std::string& chassisId) 772cf7eba09SNan Zhou { 7733ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 7741cb1a9e6SAppaRao Puli { 77545ca1b86SEd Tanous return; 77645ca1b86SEd Tanous } 777cf7eba09SNan Zhou asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 778ef4c65b7SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 779ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/ResetActionInfo", chassisId); 7801476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 7811476687dSEd Tanous 7821476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 7835b9e95a1SNan Zhou nlohmann::json::array_t parameters; 7845b9e95a1SNan Zhou nlohmann::json::object_t parameter; 7855b9e95a1SNan Zhou parameter["Name"] = "ResetType"; 7865b9e95a1SNan Zhou parameter["Required"] = true; 7875b9e95a1SNan Zhou parameter["DataType"] = "String"; 7881476687dSEd Tanous nlohmann::json::array_t allowed; 789ad539545SPatrick Williams allowed.emplace_back("PowerCycle"); 7905b9e95a1SNan Zhou parameter["AllowableValues"] = std::move(allowed); 791ad539545SPatrick Williams parameters.emplace_back(std::move(parameter)); 7925b9e95a1SNan Zhou 7931476687dSEd Tanous asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 794cf7eba09SNan Zhou } 795cf7eba09SNan Zhou 796cf7eba09SNan Zhou /** 797cf7eba09SNan Zhou * ChassisResetActionInfo derived class for delivering Chassis 798cf7eba09SNan Zhou * ResetType AllowableValues using ResetInfo schema. 799cf7eba09SNan Zhou */ 800cf7eba09SNan Zhou inline void requestRoutesChassisResetActionInfo(App& app) 801cf7eba09SNan Zhou { 802cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/") 803cf7eba09SNan Zhou .privileges(redfish::privileges::getActionInfo) 804cf7eba09SNan Zhou .methods(boost::beast::http::verb::get)( 805cf7eba09SNan Zhou std::bind_front(handleChassisResetActionInfoGet, std::ref(app))); 8061cb1a9e6SAppaRao Puli } 8071cb1a9e6SAppaRao Puli 808e37f8451SRapkiewicz, Pawel } // namespace redfish 809