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 183ccb3adbSEd Tanous #include "app.hpp" 197a1dbc48SGeorge Liu #include "dbus_utility.hpp" 20b49ac873SJames Feist #include "health.hpp" 211c8fba97SJames Feist #include "led.hpp" 223ccb3adbSEd Tanous #include "query.hpp" 233ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 243ccb3adbSEd Tanous #include "utils/collection.hpp" 253ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 26cf7eba09SNan Zhou #include "utils/json_utils.hpp" 271abe55efSEd Tanous 28e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 29*ef4c65b7SEd Tanous #include <boost/url/format.hpp> 301e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 3186d89ed7SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 321214b7e7SGunnar Mills 337a1dbc48SGeorge Liu #include <array> 347a1dbc48SGeorge Liu #include <string_view> 357a1dbc48SGeorge Liu 361abe55efSEd Tanous namespace redfish 371abe55efSEd Tanous { 38e37f8451SRapkiewicz, Pawel 39e37f8451SRapkiewicz, Pawel /** 40beeca0aeSGunnar Mills * @brief Retrieves chassis state properties over dbus 41beeca0aeSGunnar Mills * 42beeca0aeSGunnar Mills * @param[in] aResp - Shared pointer for completing asynchronous calls. 43beeca0aeSGunnar Mills * 44beeca0aeSGunnar Mills * @return None. 45beeca0aeSGunnar Mills */ 468d1b46d7Szhanghch05 inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> aResp) 47beeca0aeSGunnar Mills { 481e1e598dSJonathan Doman // crow::connections::systemBus->async_method_call( 491e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 501e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 511e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 521e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "CurrentPowerState", 535e7e2dc5SEd Tanous [aResp{std::move(aResp)}](const boost::system::error_code& ec, 541e1e598dSJonathan Doman const std::string& chassisState) { 55beeca0aeSGunnar Mills if (ec) 56beeca0aeSGunnar Mills { 57a6e5e0abSCarson Labrado if (ec == boost::system::errc::host_unreachable) 58a6e5e0abSCarson Labrado { 59a6e5e0abSCarson Labrado // Service not available, no error, just don't return 60a6e5e0abSCarson Labrado // chassis state info 61a6e5e0abSCarson Labrado BMCWEB_LOG_DEBUG << "Service not available " << ec; 62a6e5e0abSCarson Labrado return; 63a6e5e0abSCarson Labrado } 64beeca0aeSGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 65beeca0aeSGunnar Mills messages::internalError(aResp->res); 66beeca0aeSGunnar Mills return; 67beeca0aeSGunnar Mills } 68beeca0aeSGunnar Mills 691e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Chassis state: " << chassisState; 70beeca0aeSGunnar Mills // Verify Chassis State 71002d39b4SEd Tanous if (chassisState == "xyz.openbmc_project.State.Chassis.PowerState.On") 72beeca0aeSGunnar Mills { 73beeca0aeSGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 74beeca0aeSGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 75beeca0aeSGunnar Mills } 761e1e598dSJonathan Doman else if (chassisState == 77beeca0aeSGunnar Mills "xyz.openbmc_project.State.Chassis.PowerState.Off") 78beeca0aeSGunnar Mills { 79beeca0aeSGunnar Mills aResp->res.jsonValue["PowerState"] = "Off"; 80beeca0aeSGunnar Mills aResp->res.jsonValue["Status"]["State"] = "StandbyOffline"; 81beeca0aeSGunnar Mills } 821e1e598dSJonathan Doman }); 83beeca0aeSGunnar Mills } 84beeca0aeSGunnar Mills 858d1b46d7Szhanghch05 inline void getIntrusionByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 86c181942fSQiang XU const std::string& service, 87c181942fSQiang XU const std::string& objPath) 88c181942fSQiang XU { 89c181942fSQiang XU BMCWEB_LOG_DEBUG << "Get intrusion status by service \n"; 90c181942fSQiang XU 911e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 921e1e598dSJonathan Doman *crow::connections::systemBus, service, objPath, 931e1e598dSJonathan Doman "xyz.openbmc_project.Chassis.Intrusion", "Status", 945e7e2dc5SEd Tanous [aResp{std::move(aResp)}](const boost::system::error_code& ec, 951e1e598dSJonathan Doman const std::string& value) { 96c181942fSQiang XU if (ec) 97c181942fSQiang XU { 984e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 99c181942fSQiang XU // mandatory property 100c181942fSQiang XU BMCWEB_LOG_ERROR << "DBUS response error " << ec << "\n"; 101c181942fSQiang XU return; 102c181942fSQiang XU } 103c181942fSQiang XU 104002d39b4SEd Tanous aResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensorNumber"] = 1; 1051476687dSEd Tanous aResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensor"] = value; 1061e1e598dSJonathan Doman }); 107c181942fSQiang XU } 108c181942fSQiang XU 109c181942fSQiang XU /** 110c181942fSQiang XU * Retrieves physical security properties over dbus 111c181942fSQiang XU */ 1128d1b46d7Szhanghch05 inline void getPhysicalSecurityData(std::shared_ptr<bmcweb::AsyncResp> aResp) 113c181942fSQiang XU { 114e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 115e99073f5SGeorge Liu "xyz.openbmc_project.Chassis.Intrusion"}; 116e99073f5SGeorge Liu dbus::utility::getSubTree( 117e99073f5SGeorge Liu "/xyz/openbmc_project/Intrusion", 1, interfaces, 118c181942fSQiang XU [aResp{std::move(aResp)}]( 119e99073f5SGeorge Liu const boost::system::error_code& ec, 120b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 121c181942fSQiang XU if (ec) 122c181942fSQiang XU { 1234e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 124c181942fSQiang XU // mandatory property 125002d39b4SEd Tanous BMCWEB_LOG_INFO << "DBUS error: no matched iface " << ec << "\n"; 126c181942fSQiang XU return; 127c181942fSQiang XU } 128c181942fSQiang XU // Iterate over all retrieved ObjectPaths. 129c181942fSQiang XU for (const auto& object : subtree) 130c181942fSQiang XU { 131840a9ffcSPatrick Williams if (!object.second.empty()) 132c181942fSQiang XU { 133840a9ffcSPatrick Williams const auto service = object.second.front(); 134c181942fSQiang XU getIntrusionByService(aResp, service.first, object.first); 135c181942fSQiang XU return; 136c181942fSQiang XU } 137c181942fSQiang XU } 138e99073f5SGeorge Liu }); 139c181942fSQiang XU } 140c181942fSQiang XU 141cf7eba09SNan Zhou inline void handleChassisCollectionGet( 142cf7eba09SNan Zhou App& app, const crow::Request& req, 143cf7eba09SNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1441abe55efSEd Tanous { 1453ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 14645ca1b86SEd Tanous { 14745ca1b86SEd Tanous return; 14845ca1b86SEd Tanous } 1498d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 1508d1b46d7Szhanghch05 "#ChassisCollection.ChassisCollection"; 1518d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis"; 1528d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Chassis Collection"; 153e37f8451SRapkiewicz, Pawel 1547a1dbc48SGeorge Liu constexpr std::array<std::string_view, 2> interfaces{ 1557a1dbc48SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board", 1567a1dbc48SGeorge Liu "xyz.openbmc_project.Inventory.Item.Chassis"}; 15702f6ff19SGunnar Mills collection_util::getCollectionMembers( 1587a1dbc48SGeorge Liu asyncResp, boost::urls::url("/redfish/v1/Chassis"), interfaces); 159cf7eba09SNan Zhou } 160cf7eba09SNan Zhou 161cf7eba09SNan Zhou /** 162cf7eba09SNan Zhou * ChassisCollection derived class for delivering Chassis Collection Schema 163cf7eba09SNan Zhou * Functions triggers appropriate requests on DBus 164cf7eba09SNan Zhou */ 165cf7eba09SNan Zhou inline void requestRoutesChassisCollection(App& app) 166cf7eba09SNan Zhou { 167cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/") 168cf7eba09SNan Zhou .privileges(redfish::privileges::getChassisCollection) 169cf7eba09SNan Zhou .methods(boost::beast::http::verb::get)( 170cf7eba09SNan Zhou std::bind_front(handleChassisCollectionGet, std::ref(app))); 17162d5e2e4SEd Tanous } 172e37f8451SRapkiewicz, Pawel 173308f70c7SWilly Tu inline void 174308f70c7SWilly Tu getChassisLocationCode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 175308f70c7SWilly Tu const std::string& connectionName, 176308f70c7SWilly Tu const std::string& path) 177308f70c7SWilly Tu { 1781e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 1791e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 1801e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode", 1815e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec, 1821e1e598dSJonathan Doman const std::string& property) { 183308f70c7SWilly Tu if (ec) 184308f70c7SWilly Tu { 1850fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error for Location"; 186308f70c7SWilly Tu messages::internalError(asyncResp->res); 187308f70c7SWilly Tu return; 188308f70c7SWilly Tu } 189308f70c7SWilly Tu 190002d39b4SEd Tanous asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 1911e1e598dSJonathan Doman property; 1921e1e598dSJonathan Doman }); 193308f70c7SWilly Tu } 194308f70c7SWilly Tu 195308f70c7SWilly Tu inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 196308f70c7SWilly Tu const std::string& connectionName, 197308f70c7SWilly Tu const std::string& path) 198308f70c7SWilly Tu { 1991e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2001e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 2011e1e598dSJonathan Doman "xyz.openbmc_project.Common.UUID", "UUID", 2025e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec, 2031e1e598dSJonathan Doman const std::string& chassisUUID) { 204308f70c7SWilly Tu if (ec) 205308f70c7SWilly Tu { 2060fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error for UUID"; 207308f70c7SWilly Tu messages::internalError(asyncResp->res); 208308f70c7SWilly Tu return; 209308f70c7SWilly Tu } 2101e1e598dSJonathan Doman asyncResp->res.jsonValue["UUID"] = chassisUUID; 2111e1e598dSJonathan Doman }); 212308f70c7SWilly Tu } 213308f70c7SWilly Tu 214cf7eba09SNan Zhou inline void 215cf7eba09SNan Zhou handleChassisGet(App& app, const crow::Request& req, 21645ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 217cf7eba09SNan Zhou const std::string& chassisId) 218cf7eba09SNan Zhou { 2193ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 22045ca1b86SEd Tanous { 22145ca1b86SEd Tanous return; 22245ca1b86SEd Tanous } 223e99073f5SGeorge Liu constexpr std::array<std::string_view, 2> interfaces = { 224734bfe90SGunnar Mills "xyz.openbmc_project.Inventory.Item.Board", 225adc4f0dbSShawn McCarney "xyz.openbmc_project.Inventory.Item.Chassis"}; 226734bfe90SGunnar Mills 227e99073f5SGeorge Liu dbus::utility::getSubTree( 228e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 22962d5e2e4SEd Tanous [asyncResp, chassisId(std::string(chassisId))]( 230e99073f5SGeorge Liu const boost::system::error_code& ec, 231b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 23262d5e2e4SEd Tanous if (ec) 2331abe55efSEd Tanous { 234f12894f8SJason M. Bills messages::internalError(asyncResp->res); 235daf36e2eSEd Tanous return; 236daf36e2eSEd Tanous } 237daf36e2eSEd Tanous // Iterate over all retrieved ObjectPaths. 238cf7eba09SNan Zhou for (const std::pair< 239cf7eba09SNan Zhou std::string, 240cf7eba09SNan Zhou std::vector<std::pair<std::string, std::vector<std::string>>>>& 2411214b7e7SGunnar Mills object : subtree) 2421abe55efSEd Tanous { 243daf36e2eSEd Tanous const std::string& path = object.first; 244cf7eba09SNan Zhou const std::vector<std::pair<std::string, std::vector<std::string>>>& 2451214b7e7SGunnar Mills connectionNames = object.second; 2467e860f15SJohn Edward Broadbent 247997093ebSGeorge Liu sdbusplus::message::object_path objPath(path); 248997093ebSGeorge Liu if (objPath.filename() != chassisId) 2491abe55efSEd Tanous { 250daf36e2eSEd Tanous continue; 251daf36e2eSEd Tanous } 25226f03899SShawn McCarney 253002d39b4SEd Tanous auto health = std::make_shared<HealthPopulate>(asyncResp); 254b49ac873SJames Feist 2556c3e9451SGeorge Liu dbus::utility::getAssociationEndPoints( 2566c3e9451SGeorge Liu path + "/all_sensors", 2575e7e2dc5SEd Tanous [health](const boost::system::error_code& ec2, 2586c3e9451SGeorge Liu const dbus::utility::MapperEndPoints& resp) { 25923a21a1cSEd Tanous if (ec2) 260b49ac873SJames Feist { 261b49ac873SJames Feist return; // no sensors = no failures 262b49ac873SJames Feist } 2631e1e598dSJonathan Doman health->inventory = resp; 2641e1e598dSJonathan Doman }); 265b49ac873SJames Feist 266b49ac873SJames Feist health->populate(); 267b49ac873SJames Feist 26826f6976fSEd Tanous if (connectionNames.empty()) 2691abe55efSEd Tanous { 2701c8fba97SJames Feist BMCWEB_LOG_ERROR << "Got 0 Connection names"; 271e0d918bcSEd Tanous continue; 272daf36e2eSEd Tanous } 273e0d918bcSEd Tanous 27449c53ac9SJohnathan Mantey asyncResp->res.jsonValue["@odata.type"] = 275523d4868SLogananth Sundararaj "#Chassis.v1_22_0.Chassis"; 27649c53ac9SJohnathan Mantey asyncResp->res.jsonValue["@odata.id"] = 277*ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}", chassisId); 27849c53ac9SJohnathan Mantey asyncResp->res.jsonValue["Name"] = "Chassis Collection"; 27949c53ac9SJohnathan Mantey asyncResp->res.jsonValue["ChassisType"] = "RackMount"; 280cf7eba09SNan Zhou asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]["target"] = 281*ef4c65b7SEd Tanous boost::urls::format( 282*ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/Actions/Chassis.Reset", chassisId); 2831476687dSEd Tanous asyncResp->res 284cf7eba09SNan Zhou .jsonValue["Actions"]["#Chassis.Reset"]["@Redfish.ActionInfo"] = 285*ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/ResetActionInfo", 286*ef4c65b7SEd Tanous chassisId); 2871476687dSEd Tanous asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] = 288*ef4c65b7SEd Tanous "/redfish/v1/Systems/system/PCIeDevices"; 28949c53ac9SJohnathan Mantey 2906c3e9451SGeorge Liu dbus::utility::getAssociationEndPoints( 2916c3e9451SGeorge Liu path + "/drive", 2926c3e9451SGeorge Liu [asyncResp, 2936c3e9451SGeorge Liu chassisId](const boost::system::error_code& ec3, 2946c3e9451SGeorge Liu const dbus::utility::MapperEndPoints& resp) { 29592903bd4SJohn Edward Broadbent if (ec3 || resp.empty()) 29692903bd4SJohn Edward Broadbent { 29792903bd4SJohn Edward Broadbent return; // no drives = no failures 29892903bd4SJohn Edward Broadbent } 29992903bd4SJohn Edward Broadbent 30092903bd4SJohn Edward Broadbent nlohmann::json reference; 301*ef4c65b7SEd Tanous reference["@odata.id"] = boost::urls::format( 302*ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/Drives", chassisId); 30392903bd4SJohn Edward Broadbent asyncResp->res.jsonValue["Drives"] = std::move(reference); 30492903bd4SJohn Edward Broadbent }); 30592903bd4SJohn Edward Broadbent 306002d39b4SEd Tanous const std::string& connectionName = connectionNames[0].first; 3071c8fba97SJames Feist 30823a21a1cSEd Tanous const std::vector<std::string>& interfaces2 = 3091c8fba97SJames Feist connectionNames[0].second; 3101c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 3111c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 3120fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 3131c8fba97SJames Feist 314476b9cc5STejas Patil const std::string assetTagInterface = 3150fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag"; 316523d4868SLogananth Sundararaj const std::string replaceableInterface = 317523d4868SLogananth Sundararaj "xyz.openbmc_project.Inventory.Decorator.Replaceable"; 318523d4868SLogananth Sundararaj for (const auto& interface : interfaces2) 319523d4868SLogananth Sundararaj { 320523d4868SLogananth Sundararaj if (interface == assetTagInterface) 321476b9cc5STejas Patil { 3221e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 323002d39b4SEd Tanous *crow::connections::systemBus, connectionName, path, 324002d39b4SEd Tanous assetTagInterface, "AssetTag", 325523d4868SLogananth Sundararaj [asyncResp, 326523d4868SLogananth Sundararaj chassisId](const boost::system::error_code& ec2, 3271e1e598dSJonathan Doman const std::string& property) { 3288a592810SEd Tanous if (ec2) 329476b9cc5STejas Patil { 330523d4868SLogananth Sundararaj BMCWEB_LOG_ERROR 331523d4868SLogananth Sundararaj << "DBus response error for AssetTag: " << ec2; 332476b9cc5STejas Patil messages::internalError(asyncResp->res); 333476b9cc5STejas Patil return; 334476b9cc5STejas Patil } 335002d39b4SEd Tanous asyncResp->res.jsonValue["AssetTag"] = property; 3361e1e598dSJonathan Doman }); 337476b9cc5STejas Patil } 338523d4868SLogananth Sundararaj else if (interface == replaceableInterface) 339523d4868SLogananth Sundararaj { 340523d4868SLogananth Sundararaj sdbusplus::asio::getProperty<bool>( 341523d4868SLogananth Sundararaj *crow::connections::systemBus, connectionName, path, 342523d4868SLogananth Sundararaj replaceableInterface, "HotPluggable", 343523d4868SLogananth Sundararaj [asyncResp, 344523d4868SLogananth Sundararaj chassisId](const boost::system::error_code& ec2, 345523d4868SLogananth Sundararaj const bool property) { 346523d4868SLogananth Sundararaj if (ec2) 347523d4868SLogananth Sundararaj { 348523d4868SLogananth Sundararaj BMCWEB_LOG_ERROR 349523d4868SLogananth Sundararaj << "DBus response error for HotPluggable: " 350523d4868SLogananth Sundararaj << ec2; 351523d4868SLogananth Sundararaj messages::internalError(asyncResp->res); 352523d4868SLogananth Sundararaj return; 353523d4868SLogananth Sundararaj } 354523d4868SLogananth Sundararaj asyncResp->res.jsonValue["HotPluggable"] = property; 355523d4868SLogananth Sundararaj }); 356523d4868SLogananth Sundararaj } 357523d4868SLogananth Sundararaj } 358476b9cc5STejas Patil 3591c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 3601c8fba97SJames Feist { 361002d39b4SEd Tanous if (std::find(interfaces2.begin(), interfaces2.end(), 36223a21a1cSEd Tanous interface) != interfaces2.end()) 3631c8fba97SJames Feist { 3641c8fba97SJames Feist getIndicatorLedState(asyncResp); 3659f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 3661c8fba97SJames Feist break; 3671c8fba97SJames Feist } 3681c8fba97SJames Feist } 3691c8fba97SJames Feist 37086d89ed7SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 37186d89ed7SKrzysztof Grobelny *crow::connections::systemBus, connectionName, path, 37286d89ed7SKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 37362d5e2e4SEd Tanous [asyncResp, chassisId(std::string(chassisId))]( 3745e7e2dc5SEd Tanous const boost::system::error_code& /*ec2*/, 375cf7eba09SNan Zhou const dbus::utility::DBusPropertiesMap& propertiesList) { 37686d89ed7SKrzysztof Grobelny const std::string* partNumber = nullptr; 37786d89ed7SKrzysztof Grobelny const std::string* serialNumber = nullptr; 37886d89ed7SKrzysztof Grobelny const std::string* manufacturer = nullptr; 37986d89ed7SKrzysztof Grobelny const std::string* model = nullptr; 38086d89ed7SKrzysztof Grobelny const std::string* sparePartNumber = nullptr; 38186d89ed7SKrzysztof Grobelny 38286d89ed7SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 38386d89ed7SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), propertiesList, 38486d89ed7SKrzysztof Grobelny "PartNumber", partNumber, "SerialNumber", serialNumber, 38586d89ed7SKrzysztof Grobelny "Manufacturer", manufacturer, "Model", model, 38686d89ed7SKrzysztof Grobelny "SparePartNumber", sparePartNumber); 38786d89ed7SKrzysztof Grobelny 38886d89ed7SKrzysztof Grobelny if (!success) 3891abe55efSEd Tanous { 390002d39b4SEd Tanous messages::internalError(asyncResp->res); 391caa11f7aSAlpana Kumari return; 392daf36e2eSEd Tanous } 39386d89ed7SKrzysztof Grobelny 39486d89ed7SKrzysztof Grobelny if (partNumber != nullptr) 39586d89ed7SKrzysztof Grobelny { 39686d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["PartNumber"] = *partNumber; 39786d89ed7SKrzysztof Grobelny } 39886d89ed7SKrzysztof Grobelny 39986d89ed7SKrzysztof Grobelny if (serialNumber != nullptr) 40086d89ed7SKrzysztof Grobelny { 40186d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 40286d89ed7SKrzysztof Grobelny } 40386d89ed7SKrzysztof Grobelny 40486d89ed7SKrzysztof Grobelny if (manufacturer != nullptr) 40586d89ed7SKrzysztof Grobelny { 40686d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["Manufacturer"] = *manufacturer; 40786d89ed7SKrzysztof Grobelny } 40886d89ed7SKrzysztof Grobelny 40986d89ed7SKrzysztof Grobelny if (model != nullptr) 41086d89ed7SKrzysztof Grobelny { 41186d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["Model"] = *model; 41286d89ed7SKrzysztof Grobelny } 41386d89ed7SKrzysztof Grobelny 414caa11f7aSAlpana Kumari // SparePartNumber is optional on D-Bus 415caa11f7aSAlpana Kumari // so skip if it is empty 41686d89ed7SKrzysztof Grobelny if (sparePartNumber != nullptr && !sparePartNumber->empty()) 417caa11f7aSAlpana Kumari { 41886d89ed7SKrzysztof Grobelny asyncResp->res.jsonValue["SparePartNumber"] = 41986d89ed7SKrzysztof Grobelny *sparePartNumber; 420caa11f7aSAlpana Kumari } 42186d89ed7SKrzysztof Grobelny 42262d5e2e4SEd Tanous asyncResp->res.jsonValue["Name"] = chassisId; 42362d5e2e4SEd Tanous asyncResp->res.jsonValue["Id"] = chassisId; 4240256b694Szhanghch05 #ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL 425002d39b4SEd Tanous asyncResp->res.jsonValue["Thermal"]["@odata.id"] = 426*ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/Thermal", 427*ef4c65b7SEd Tanous chassisId); 4282474adfaSEd Tanous // Power object 4291476687dSEd Tanous asyncResp->res.jsonValue["Power"]["@odata.id"] = 430*ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/Power", 431*ef4c65b7SEd Tanous chassisId); 4320256b694Szhanghch05 #endif 4332973963eSXiaochao Ma #ifdef BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM 4342973963eSXiaochao Ma asyncResp->res.jsonValue["ThermalSubsystem"]["@odata.id"] = 435*ef4c65b7SEd Tanous boost::urls::format( 436*ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/ThermalSubsystem", chassisId); 43777b36437SChicago Duan asyncResp->res.jsonValue["PowerSubsystem"]["@odata.id"] = 438*ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/PowerSubsystem", 439*ef4c65b7SEd Tanous chassisId); 4404ca3ec3cSAlbert Zhang asyncResp->res.jsonValue["EnvironmentMetrics"]["@odata.id"] = 441*ef4c65b7SEd Tanous boost::urls::format( 442*ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/EnvironmentMetrics", chassisId); 4432973963eSXiaochao Ma #endif 44495a3ecadSAnthony Wilson // SensorCollection 445002d39b4SEd Tanous asyncResp->res.jsonValue["Sensors"]["@odata.id"] = 446*ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Chassis/{}/Sensors", 447*ef4c65b7SEd Tanous chassisId); 448002d39b4SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 4491476687dSEd Tanous 4501476687dSEd Tanous nlohmann::json::array_t computerSystems; 4511476687dSEd Tanous nlohmann::json::object_t system; 452002d39b4SEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 453ad539545SPatrick Williams computerSystems.emplace_back(std::move(system)); 454002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ComputerSystems"] = 4551476687dSEd Tanous std::move(computerSystems); 4561476687dSEd Tanous 4571476687dSEd Tanous nlohmann::json::array_t managedBy; 4581476687dSEd Tanous nlohmann::json::object_t manager; 459002d39b4SEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 460ad539545SPatrick Williams managedBy.emplace_back(std::move(manager)); 4617e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Links"]["ManagedBy"] = 4621476687dSEd Tanous std::move(managedBy); 463beeca0aeSGunnar Mills getChassisState(asyncResp); 46486d89ed7SKrzysztof Grobelny }); 4652c37b4b0SSharad Yadav 466308f70c7SWilly Tu for (const auto& interface : interfaces2) 4672c37b4b0SSharad Yadav { 468308f70c7SWilly Tu if (interface == "xyz.openbmc_project.Common.UUID") 4692c37b4b0SSharad Yadav { 470308f70c7SWilly Tu getChassisUUID(asyncResp, connectionName, path); 4712c37b4b0SSharad Yadav } 472cf7eba09SNan Zhou else if (interface == 4730fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.LocationCode") 4742c37b4b0SSharad Yadav { 475002d39b4SEd Tanous getChassisLocationCode(asyncResp, connectionName, path); 4762c37b4b0SSharad Yadav } 4772c37b4b0SSharad Yadav } 4782c37b4b0SSharad Yadav 479daf36e2eSEd Tanous return; 480daf36e2eSEd Tanous } 481e0d918bcSEd Tanous 482daf36e2eSEd Tanous // Couldn't find an object with that name. return an error 483d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); 484e99073f5SGeorge Liu }); 485c181942fSQiang XU 486c181942fSQiang XU getPhysicalSecurityData(asyncResp); 487cf7eba09SNan Zhou } 4881c8fba97SJames Feist 489cf7eba09SNan Zhou inline void 490cf7eba09SNan Zhou handleChassisPatch(App& app, const crow::Request& req, 4917e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 492cf7eba09SNan Zhou const std::string& param) 493cf7eba09SNan Zhou { 4943ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 49545ca1b86SEd Tanous { 49645ca1b86SEd Tanous return; 49745ca1b86SEd Tanous } 4989f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 4991c8fba97SJames Feist std::optional<std::string> indicatorLed; 5001c8fba97SJames Feist 5017e860f15SJohn Edward Broadbent if (param.empty()) 5021c8fba97SJames Feist { 5031c8fba97SJames Feist return; 5041c8fba97SJames Feist } 5051c8fba97SJames Feist 50615ed6780SWilly Tu if (!json_util::readJsonPatch( 5077e860f15SJohn Edward Broadbent req, asyncResp->res, "LocationIndicatorActive", 5087e860f15SJohn Edward Broadbent locationIndicatorActive, "IndicatorLED", indicatorLed)) 5091c8fba97SJames Feist { 5101c8fba97SJames Feist return; 5111c8fba97SJames Feist } 5121c8fba97SJames Feist 5139f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 5149f8bfa7cSGunnar Mills if (!locationIndicatorActive && !indicatorLed) 5151c8fba97SJames Feist { 5161c8fba97SJames Feist return; // delete this when we support more patch properties 5171c8fba97SJames Feist } 518d6aa0093SGunnar Mills if (indicatorLed) 519d6aa0093SGunnar Mills { 5207e860f15SJohn Edward Broadbent asyncResp->res.addHeader( 5217e860f15SJohn Edward Broadbent boost::beast::http::field::warning, 5220fda0f12SGeorge Liu "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\""); 523d6aa0093SGunnar Mills } 5241c8fba97SJames Feist 525e99073f5SGeorge Liu constexpr std::array<std::string_view, 2> interfaces = { 5261c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Board", 5271c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Chassis"}; 5281c8fba97SJames Feist 5297e860f15SJohn Edward Broadbent const std::string& chassisId = param; 5301c8fba97SJames Feist 531e99073f5SGeorge Liu dbus::utility::getSubTree( 532e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 533cf7eba09SNan Zhou [asyncResp, chassisId, locationIndicatorActive, 5345e7e2dc5SEd Tanous indicatorLed](const boost::system::error_code& ec, 535b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 5361c8fba97SJames Feist if (ec) 5371c8fba97SJames Feist { 5381c8fba97SJames Feist messages::internalError(asyncResp->res); 5391c8fba97SJames Feist return; 5401c8fba97SJames Feist } 5411c8fba97SJames Feist 5421c8fba97SJames Feist // Iterate over all retrieved ObjectPaths. 543cf7eba09SNan Zhou for (const std::pair< 544cf7eba09SNan Zhou std::string, 545cf7eba09SNan Zhou std::vector<std::pair<std::string, std::vector<std::string>>>>& 5461214b7e7SGunnar Mills object : subtree) 5471c8fba97SJames Feist { 5481c8fba97SJames Feist const std::string& path = object.first; 549cf7eba09SNan Zhou const std::vector<std::pair<std::string, std::vector<std::string>>>& 5501214b7e7SGunnar Mills connectionNames = object.second; 5511c8fba97SJames Feist 552997093ebSGeorge Liu sdbusplus::message::object_path objPath(path); 553997093ebSGeorge Liu if (objPath.filename() != chassisId) 5541c8fba97SJames Feist { 5551c8fba97SJames Feist continue; 5561c8fba97SJames Feist } 5571c8fba97SJames Feist 55826f6976fSEd Tanous if (connectionNames.empty()) 5591c8fba97SJames Feist { 5601c8fba97SJames Feist BMCWEB_LOG_ERROR << "Got 0 Connection names"; 5611c8fba97SJames Feist continue; 5621c8fba97SJames Feist } 5631c8fba97SJames Feist 56423a21a1cSEd Tanous const std::vector<std::string>& interfaces3 = 5651c8fba97SJames Feist connectionNames[0].second; 5661c8fba97SJames Feist 5671c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 5681c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 5690fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 5701c8fba97SJames Feist bool indicatorChassis = false; 5711c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 5721c8fba97SJames Feist { 573002d39b4SEd Tanous if (std::find(interfaces3.begin(), interfaces3.end(), 57423a21a1cSEd Tanous interface) != interfaces3.end()) 5751c8fba97SJames Feist { 5761c8fba97SJames Feist indicatorChassis = true; 5771c8fba97SJames Feist break; 5781c8fba97SJames Feist } 5791c8fba97SJames Feist } 5809f8bfa7cSGunnar Mills if (locationIndicatorActive) 5819f8bfa7cSGunnar Mills { 5829f8bfa7cSGunnar Mills if (indicatorChassis) 5839f8bfa7cSGunnar Mills { 584002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, 585002d39b4SEd Tanous *locationIndicatorActive); 5869f8bfa7cSGunnar Mills } 5879f8bfa7cSGunnar Mills else 5889f8bfa7cSGunnar Mills { 589002d39b4SEd Tanous messages::propertyUnknown(asyncResp->res, 590002d39b4SEd Tanous "LocationIndicatorActive"); 5919f8bfa7cSGunnar Mills } 5929f8bfa7cSGunnar Mills } 5939f8bfa7cSGunnar Mills if (indicatorLed) 5949f8bfa7cSGunnar Mills { 5951c8fba97SJames Feist if (indicatorChassis) 5961c8fba97SJames Feist { 597f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 5981c8fba97SJames Feist } 5991c8fba97SJames Feist else 6001c8fba97SJames Feist { 601cf7eba09SNan Zhou messages::propertyUnknown(asyncResp->res, "IndicatorLED"); 6021c8fba97SJames Feist } 6031c8fba97SJames Feist } 6041c8fba97SJames Feist return; 6051c8fba97SJames Feist } 6061c8fba97SJames Feist 607d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); 608e99073f5SGeorge Liu }); 609cf7eba09SNan Zhou } 610cf7eba09SNan Zhou 611cf7eba09SNan Zhou /** 612cf7eba09SNan Zhou * Chassis override class for delivering Chassis Schema 613cf7eba09SNan Zhou * Functions triggers appropriate requests on DBus 614cf7eba09SNan Zhou */ 615cf7eba09SNan Zhou inline void requestRoutesChassis(App& app) 616cf7eba09SNan Zhou { 617cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 618cf7eba09SNan Zhou .privileges(redfish::privileges::getChassis) 619cf7eba09SNan Zhou .methods(boost::beast::http::verb::get)( 620cf7eba09SNan Zhou std::bind_front(handleChassisGet, std::ref(app))); 621cf7eba09SNan Zhou 622cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 623cf7eba09SNan Zhou .privileges(redfish::privileges::patchChassis) 624cf7eba09SNan Zhou .methods(boost::beast::http::verb::patch)( 625cf7eba09SNan Zhou std::bind_front(handleChassisPatch, std::ref(app))); 6261c8fba97SJames Feist } 627dd99e04bSP.K. Lee 6288d1b46d7Szhanghch05 inline void 6298d1b46d7Szhanghch05 doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 630dd99e04bSP.K. Lee { 6317a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 632c3b3c92aSVijay Khemka "xyz.openbmc_project.State.Chassis"}; 633c3b3c92aSVijay Khemka 634c3b3c92aSVijay Khemka // Use mapper to get subtree paths. 6357a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 6367a1dbc48SGeorge Liu "/", 0, interfaces, 637b9d36b47SEd Tanous [asyncResp]( 6387a1dbc48SGeorge Liu const boost::system::error_code& ec, 639b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreePathsResponse& chassisList) { 640c3b3c92aSVijay Khemka if (ec) 641c3b3c92aSVijay Khemka { 642c3b3c92aSVijay Khemka BMCWEB_LOG_DEBUG << "[mapper] Bad D-Bus request error: " << ec; 643c3b3c92aSVijay Khemka messages::internalError(asyncResp->res); 644c3b3c92aSVijay Khemka return; 645c3b3c92aSVijay Khemka } 646c3b3c92aSVijay Khemka 647dd99e04bSP.K. Lee const char* processName = "xyz.openbmc_project.State.Chassis"; 648dd99e04bSP.K. Lee const char* interfaceName = "xyz.openbmc_project.State.Chassis"; 649dd99e04bSP.K. Lee const char* destProperty = "RequestedPowerTransition"; 650dd99e04bSP.K. Lee const std::string propertyValue = 651dd99e04bSP.K. Lee "xyz.openbmc_project.State.Chassis.Transition.PowerCycle"; 652002d39b4SEd Tanous std::string objectPath = "/xyz/openbmc_project/state/chassis_system0"; 653c3b3c92aSVijay Khemka 654c3b3c92aSVijay Khemka /* Look for system reset chassis path */ 655002d39b4SEd Tanous if ((std::find(chassisList.begin(), chassisList.end(), objectPath)) == 656002d39b4SEd Tanous chassisList.end()) 657c3b3c92aSVijay Khemka { 658c3b3c92aSVijay Khemka /* We prefer to reset the full chassis_system, but if it doesn't 659c3b3c92aSVijay Khemka * exist on some platforms, fall back to a host-only power reset 660c3b3c92aSVijay Khemka */ 661c3b3c92aSVijay Khemka objectPath = "/xyz/openbmc_project/state/chassis0"; 662c3b3c92aSVijay Khemka } 663dd99e04bSP.K. Lee 664dd99e04bSP.K. Lee crow::connections::systemBus->async_method_call( 6655e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 666dd99e04bSP.K. Lee // Use "Set" method to set the property value. 6678a592810SEd Tanous if (ec2) 668dd99e04bSP.K. Lee { 6698a592810SEd Tanous BMCWEB_LOG_DEBUG << "[Set] Bad D-Bus request error: " << ec2; 670dd99e04bSP.K. Lee messages::internalError(asyncResp->res); 671dd99e04bSP.K. Lee return; 672dd99e04bSP.K. Lee } 673dd99e04bSP.K. Lee 674dd99e04bSP.K. Lee messages::success(asyncResp->res); 675dd99e04bSP.K. Lee }, 676002d39b4SEd Tanous processName, objectPath, "org.freedesktop.DBus.Properties", "Set", 677002d39b4SEd Tanous interfaceName, destProperty, 678168e20c1SEd Tanous dbus::utility::DbusVariantType{propertyValue}); 6797a1dbc48SGeorge Liu }); 680dd99e04bSP.K. Lee } 681dd99e04bSP.K. Lee 682cf7eba09SNan Zhou inline void handleChassisResetActionInfoPost( 683cf7eba09SNan Zhou App& app, const crow::Request& req, 6847e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 685cf7eba09SNan Zhou const std::string& /*chassisId*/) 686cf7eba09SNan Zhou { 6873ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 68845ca1b86SEd Tanous { 68945ca1b86SEd Tanous return; 69045ca1b86SEd Tanous } 691dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Post Chassis Reset."; 692dd99e04bSP.K. Lee 693dd99e04bSP.K. Lee std::string resetType; 694dd99e04bSP.K. Lee 695cf7eba09SNan Zhou if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 696dd99e04bSP.K. Lee { 697dd99e04bSP.K. Lee return; 698dd99e04bSP.K. Lee } 699dd99e04bSP.K. Lee 700dd99e04bSP.K. Lee if (resetType != "PowerCycle") 701dd99e04bSP.K. Lee { 702dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: " 703dd99e04bSP.K. Lee << resetType; 704002d39b4SEd Tanous messages::actionParameterNotSupported(asyncResp->res, resetType, 705002d39b4SEd Tanous "ResetType"); 706dd99e04bSP.K. Lee 707dd99e04bSP.K. Lee return; 708dd99e04bSP.K. Lee } 709dd99e04bSP.K. Lee doChassisPowerCycle(asyncResp); 710dd99e04bSP.K. Lee } 7111cb1a9e6SAppaRao Puli 7121cb1a9e6SAppaRao Puli /** 713cf7eba09SNan Zhou * ChassisResetAction class supports the POST method for the Reset 714cf7eba09SNan Zhou * action. 715cf7eba09SNan Zhou * Function handles POST method request. 716cf7eba09SNan Zhou * Analyzes POST body before sending Reset request data to D-Bus. 7171cb1a9e6SAppaRao Puli */ 718cf7eba09SNan Zhou 719cf7eba09SNan Zhou inline void requestRoutesChassisResetAction(App& app) 7201cb1a9e6SAppaRao Puli { 721cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/") 722cf7eba09SNan Zhou .privileges(redfish::privileges::postChassis) 723cf7eba09SNan Zhou .methods(boost::beast::http::verb::post)( 724cf7eba09SNan Zhou std::bind_front(handleChassisResetActionInfoPost, std::ref(app))); 725cf7eba09SNan Zhou } 726cf7eba09SNan Zhou 727cf7eba09SNan Zhou inline void handleChassisResetActionInfoGet( 728cf7eba09SNan Zhou App& app, const crow::Request& req, 7297e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 730cf7eba09SNan Zhou const std::string& chassisId) 731cf7eba09SNan Zhou { 7323ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 7331cb1a9e6SAppaRao Puli { 73445ca1b86SEd Tanous return; 73545ca1b86SEd Tanous } 736cf7eba09SNan Zhou asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 737*ef4c65b7SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 738*ef4c65b7SEd Tanous "/redfish/v1/Chassis/{}/ResetActionInfo", chassisId); 7391476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 7401476687dSEd Tanous 7411476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 7425b9e95a1SNan Zhou nlohmann::json::array_t parameters; 7435b9e95a1SNan Zhou nlohmann::json::object_t parameter; 7445b9e95a1SNan Zhou parameter["Name"] = "ResetType"; 7455b9e95a1SNan Zhou parameter["Required"] = true; 7465b9e95a1SNan Zhou parameter["DataType"] = "String"; 7471476687dSEd Tanous nlohmann::json::array_t allowed; 748ad539545SPatrick Williams allowed.emplace_back("PowerCycle"); 7495b9e95a1SNan Zhou parameter["AllowableValues"] = std::move(allowed); 750ad539545SPatrick Williams parameters.emplace_back(std::move(parameter)); 7515b9e95a1SNan Zhou 7521476687dSEd Tanous asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 753cf7eba09SNan Zhou } 754cf7eba09SNan Zhou 755cf7eba09SNan Zhou /** 756cf7eba09SNan Zhou * ChassisResetActionInfo derived class for delivering Chassis 757cf7eba09SNan Zhou * ResetType AllowableValues using ResetInfo schema. 758cf7eba09SNan Zhou */ 759cf7eba09SNan Zhou inline void requestRoutesChassisResetActionInfo(App& app) 760cf7eba09SNan Zhou { 761cf7eba09SNan Zhou BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/") 762cf7eba09SNan Zhou .privileges(redfish::privileges::getActionInfo) 763cf7eba09SNan Zhou .methods(boost::beast::http::verb::get)( 764cf7eba09SNan Zhou std::bind_front(handleChassisResetActionInfoGet, std::ref(app))); 7651cb1a9e6SAppaRao Puli } 7661cb1a9e6SAppaRao Puli 767e37f8451SRapkiewicz, Pawel } // namespace redfish 768