xref: /openbmc/bmcweb/features/redfish/lib/chassis.hpp (revision 3ccb3adb9a14783f6bef601506de9f8bcae22d51)
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 
18*3ccb3adbSEd Tanous #include "app.hpp"
197a1dbc48SGeorge Liu #include "dbus_utility.hpp"
20b49ac873SJames Feist #include "health.hpp"
211c8fba97SJames Feist #include "led.hpp"
22*3ccb3adbSEd Tanous #include "query.hpp"
23*3ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
24*3ccb3adbSEd Tanous #include "utils/collection.hpp"
25*3ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
26cf7eba09SNan Zhou #include "utils/json_utils.hpp"
271abe55efSEd Tanous 
281e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
2986d89ed7SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
301214b7e7SGunnar Mills 
317a1dbc48SGeorge Liu #include <array>
327a1dbc48SGeorge Liu #include <string_view>
337a1dbc48SGeorge Liu 
341abe55efSEd Tanous namespace redfish
351abe55efSEd Tanous {
36e37f8451SRapkiewicz, Pawel 
37e37f8451SRapkiewicz, Pawel /**
38beeca0aeSGunnar Mills  * @brief Retrieves chassis state properties over dbus
39beeca0aeSGunnar Mills  *
40beeca0aeSGunnar Mills  * @param[in] aResp - Shared pointer for completing asynchronous calls.
41beeca0aeSGunnar Mills  *
42beeca0aeSGunnar Mills  * @return None.
43beeca0aeSGunnar Mills  */
448d1b46d7Szhanghch05 inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> aResp)
45beeca0aeSGunnar Mills {
461e1e598dSJonathan Doman     // crow::connections::systemBus->async_method_call(
471e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
481e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
491e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
501e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "CurrentPowerState",
511e1e598dSJonathan Doman         [aResp{std::move(aResp)}](const boost::system::error_code ec,
521e1e598dSJonathan Doman                                   const std::string& chassisState) {
53beeca0aeSGunnar Mills         if (ec)
54beeca0aeSGunnar Mills         {
55a6e5e0abSCarson Labrado             if (ec == boost::system::errc::host_unreachable)
56a6e5e0abSCarson Labrado             {
57a6e5e0abSCarson Labrado                 // Service not available, no error, just don't return
58a6e5e0abSCarson Labrado                 // chassis state info
59a6e5e0abSCarson Labrado                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
60a6e5e0abSCarson Labrado                 return;
61a6e5e0abSCarson Labrado             }
62beeca0aeSGunnar Mills             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
63beeca0aeSGunnar Mills             messages::internalError(aResp->res);
64beeca0aeSGunnar Mills             return;
65beeca0aeSGunnar Mills         }
66beeca0aeSGunnar Mills 
671e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Chassis state: " << chassisState;
68beeca0aeSGunnar Mills         // Verify Chassis State
69002d39b4SEd Tanous         if (chassisState == "xyz.openbmc_project.State.Chassis.PowerState.On")
70beeca0aeSGunnar Mills         {
71beeca0aeSGunnar Mills             aResp->res.jsonValue["PowerState"] = "On";
72beeca0aeSGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "Enabled";
73beeca0aeSGunnar Mills         }
741e1e598dSJonathan Doman         else if (chassisState ==
75beeca0aeSGunnar Mills                  "xyz.openbmc_project.State.Chassis.PowerState.Off")
76beeca0aeSGunnar Mills         {
77beeca0aeSGunnar Mills             aResp->res.jsonValue["PowerState"] = "Off";
78beeca0aeSGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "StandbyOffline";
79beeca0aeSGunnar Mills         }
801e1e598dSJonathan Doman         });
81beeca0aeSGunnar Mills }
82beeca0aeSGunnar Mills 
838d1b46d7Szhanghch05 inline void getIntrusionByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
84c181942fSQiang XU                                   const std::string& service,
85c181942fSQiang XU                                   const std::string& objPath)
86c181942fSQiang XU {
87c181942fSQiang XU     BMCWEB_LOG_DEBUG << "Get intrusion status by service \n";
88c181942fSQiang XU 
891e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
901e1e598dSJonathan Doman         *crow::connections::systemBus, service, objPath,
911e1e598dSJonathan Doman         "xyz.openbmc_project.Chassis.Intrusion", "Status",
92c181942fSQiang XU         [aResp{std::move(aResp)}](const boost::system::error_code ec,
931e1e598dSJonathan Doman                                   const std::string& value) {
94c181942fSQiang XU         if (ec)
95c181942fSQiang XU         {
964e0453b1SGunnar Mills             // do not add err msg in redfish response, because this is not
97c181942fSQiang XU             //     mandatory property
98c181942fSQiang XU             BMCWEB_LOG_ERROR << "DBUS response error " << ec << "\n";
99c181942fSQiang XU             return;
100c181942fSQiang XU         }
101c181942fSQiang XU 
102002d39b4SEd Tanous         aResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensorNumber"] = 1;
1031476687dSEd Tanous         aResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensor"] = value;
1041e1e598dSJonathan Doman         });
105c181942fSQiang XU }
106c181942fSQiang XU 
107c181942fSQiang XU /**
108c181942fSQiang XU  * Retrieves physical security properties over dbus
109c181942fSQiang XU  */
1108d1b46d7Szhanghch05 inline void getPhysicalSecurityData(std::shared_ptr<bmcweb::AsyncResp> aResp)
111c181942fSQiang XU {
112c181942fSQiang XU     crow::connections::systemBus->async_method_call(
113c181942fSQiang XU         [aResp{std::move(aResp)}](
114c181942fSQiang XU             const boost::system::error_code ec,
115b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
116c181942fSQiang XU         if (ec)
117c181942fSQiang XU         {
1184e0453b1SGunnar Mills             // do not add err msg in redfish response, because this is not
119c181942fSQiang XU             //     mandatory property
120002d39b4SEd Tanous             BMCWEB_LOG_INFO << "DBUS error: no matched iface " << ec << "\n";
121c181942fSQiang XU             return;
122c181942fSQiang XU         }
123c181942fSQiang XU         // Iterate over all retrieved ObjectPaths.
124c181942fSQiang XU         for (const auto& object : subtree)
125c181942fSQiang XU         {
126c181942fSQiang XU             for (const auto& service : object.second)
127c181942fSQiang XU             {
128c181942fSQiang XU                 getIntrusionByService(aResp, service.first, object.first);
129c181942fSQiang XU                 return;
130c181942fSQiang XU             }
131c181942fSQiang XU         }
132c181942fSQiang XU         },
133c181942fSQiang XU         "xyz.openbmc_project.ObjectMapper",
134c181942fSQiang XU         "/xyz/openbmc_project/object_mapper",
135c181942fSQiang XU         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
136271584abSEd Tanous         "/xyz/openbmc_project/Intrusion", 1,
137c181942fSQiang XU         std::array<const char*, 1>{"xyz.openbmc_project.Chassis.Intrusion"});
138c181942fSQiang XU }
139c181942fSQiang XU 
140cf7eba09SNan Zhou inline void handleChassisCollectionGet(
141cf7eba09SNan Zhou     App& app, const crow::Request& req,
142cf7eba09SNan Zhou     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1431abe55efSEd Tanous {
1443ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
14545ca1b86SEd Tanous     {
14645ca1b86SEd Tanous         return;
14745ca1b86SEd Tanous     }
1488d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
1498d1b46d7Szhanghch05         "#ChassisCollection.ChassisCollection";
1508d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
1518d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Chassis Collection";
152e37f8451SRapkiewicz, Pawel 
1537a1dbc48SGeorge Liu     constexpr std::array<std::string_view, 2> interfaces{
1547a1dbc48SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Board",
1557a1dbc48SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Chassis"};
15602f6ff19SGunnar Mills     collection_util::getCollectionMembers(
1577a1dbc48SGeorge Liu         asyncResp, boost::urls::url("/redfish/v1/Chassis"), interfaces);
158cf7eba09SNan Zhou }
159cf7eba09SNan Zhou 
160cf7eba09SNan Zhou /**
161cf7eba09SNan Zhou  * ChassisCollection derived class for delivering Chassis Collection Schema
162cf7eba09SNan Zhou  *  Functions triggers appropriate requests on DBus
163cf7eba09SNan Zhou  */
164cf7eba09SNan Zhou inline void requestRoutesChassisCollection(App& app)
165cf7eba09SNan Zhou {
166cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/")
167cf7eba09SNan Zhou         .privileges(redfish::privileges::getChassisCollection)
168cf7eba09SNan Zhou         .methods(boost::beast::http::verb::get)(
169cf7eba09SNan Zhou             std::bind_front(handleChassisCollectionGet, std::ref(app)));
17062d5e2e4SEd Tanous }
171e37f8451SRapkiewicz, Pawel 
172308f70c7SWilly Tu inline void
173308f70c7SWilly Tu     getChassisLocationCode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
174308f70c7SWilly Tu                            const std::string& connectionName,
175308f70c7SWilly Tu                            const std::string& path)
176308f70c7SWilly Tu {
1771e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
1781e1e598dSJonathan Doman         *crow::connections::systemBus, connectionName, path,
1791e1e598dSJonathan Doman         "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
180308f70c7SWilly Tu         [asyncResp](const boost::system::error_code ec,
1811e1e598dSJonathan Doman                     const std::string& property) {
182308f70c7SWilly Tu         if (ec)
183308f70c7SWilly Tu         {
1840fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error for Location";
185308f70c7SWilly Tu             messages::internalError(asyncResp->res);
186308f70c7SWilly Tu             return;
187308f70c7SWilly Tu         }
188308f70c7SWilly Tu 
189002d39b4SEd Tanous         asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
1901e1e598dSJonathan Doman             property;
1911e1e598dSJonathan Doman         });
192308f70c7SWilly Tu }
193308f70c7SWilly Tu 
194308f70c7SWilly Tu inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
195308f70c7SWilly Tu                            const std::string& connectionName,
196308f70c7SWilly Tu                            const std::string& path)
197308f70c7SWilly Tu {
1981e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
1991e1e598dSJonathan Doman         *crow::connections::systemBus, connectionName, path,
2001e1e598dSJonathan Doman         "xyz.openbmc_project.Common.UUID", "UUID",
201308f70c7SWilly Tu         [asyncResp](const boost::system::error_code ec,
2021e1e598dSJonathan Doman                     const std::string& chassisUUID) {
203308f70c7SWilly Tu         if (ec)
204308f70c7SWilly Tu         {
2050fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error for UUID";
206308f70c7SWilly Tu             messages::internalError(asyncResp->res);
207308f70c7SWilly Tu             return;
208308f70c7SWilly Tu         }
2091e1e598dSJonathan Doman         asyncResp->res.jsonValue["UUID"] = chassisUUID;
2101e1e598dSJonathan Doman         });
211308f70c7SWilly Tu }
212308f70c7SWilly Tu 
213cf7eba09SNan Zhou inline void
214cf7eba09SNan Zhou     handleChassisGet(App& app, const crow::Request& req,
21545ca1b86SEd Tanous                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
216cf7eba09SNan Zhou                      const std::string& chassisId)
217cf7eba09SNan Zhou {
2183ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
21945ca1b86SEd Tanous     {
22045ca1b86SEd Tanous         return;
22145ca1b86SEd Tanous     }
222adc4f0dbSShawn McCarney     const std::array<const char*, 2> interfaces = {
223734bfe90SGunnar Mills         "xyz.openbmc_project.Inventory.Item.Board",
224adc4f0dbSShawn McCarney         "xyz.openbmc_project.Inventory.Item.Chassis"};
225734bfe90SGunnar Mills 
22655c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
22762d5e2e4SEd Tanous         [asyncResp, chassisId(std::string(chassisId))](
22862d5e2e4SEd Tanous             const boost::system::error_code ec,
229b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
23062d5e2e4SEd Tanous         if (ec)
2311abe55efSEd Tanous         {
232f12894f8SJason M. Bills             messages::internalError(asyncResp->res);
233daf36e2eSEd Tanous             return;
234daf36e2eSEd Tanous         }
235daf36e2eSEd Tanous         // Iterate over all retrieved ObjectPaths.
236cf7eba09SNan Zhou         for (const std::pair<
237cf7eba09SNan Zhou                  std::string,
238cf7eba09SNan Zhou                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
2391214b7e7SGunnar Mills                  object : subtree)
2401abe55efSEd Tanous         {
241daf36e2eSEd Tanous             const std::string& path = object.first;
242cf7eba09SNan Zhou             const std::vector<std::pair<std::string, std::vector<std::string>>>&
2431214b7e7SGunnar Mills                 connectionNames = object.second;
2447e860f15SJohn Edward Broadbent 
245997093ebSGeorge Liu             sdbusplus::message::object_path objPath(path);
246997093ebSGeorge Liu             if (objPath.filename() != chassisId)
2471abe55efSEd Tanous             {
248daf36e2eSEd Tanous                 continue;
249daf36e2eSEd Tanous             }
25026f03899SShawn McCarney 
251002d39b4SEd Tanous             auto health = std::make_shared<HealthPopulate>(asyncResp);
252b49ac873SJames Feist 
2531e1e598dSJonathan Doman             sdbusplus::asio::getProperty<std::vector<std::string>>(
2541e1e598dSJonathan Doman                 *crow::connections::systemBus,
255002d39b4SEd Tanous                 "xyz.openbmc_project.ObjectMapper", path + "/all_sensors",
2561e1e598dSJonathan Doman                 "xyz.openbmc_project.Association", "endpoints",
257168e20c1SEd Tanous                 [health](const boost::system::error_code ec2,
2581e1e598dSJonathan Doman                          const std::vector<std::string>& 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"] =
2755ac5a2f4SGunnar Mills                 "#Chassis.v1_16_0.Chassis";
27649c53ac9SJohnathan Mantey             asyncResp->res.jsonValue["@odata.id"] =
27749c53ac9SJohnathan Mantey                 "/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"] =
281cf7eba09SNan Zhou                 "/redfish/v1/Chassis/" + chassisId + "/Actions/Chassis.Reset";
2821476687dSEd Tanous             asyncResp->res
283cf7eba09SNan Zhou                 .jsonValue["Actions"]["#Chassis.Reset"]["@Redfish.ActionInfo"] =
284002d39b4SEd Tanous                 "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
2851476687dSEd Tanous             asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] =
2861476687dSEd Tanous                 "/redfish/v1/Systems/system/PCIeDevices";
28749c53ac9SJohnathan Mantey 
28892903bd4SJohn Edward Broadbent             sdbusplus::asio::getProperty<std::vector<std::string>>(
28992903bd4SJohn Edward Broadbent                 *crow::connections::systemBus,
29092903bd4SJohn Edward Broadbent                 "xyz.openbmc_project.ObjectMapper", path + "/drive",
29192903bd4SJohn Edward Broadbent                 "xyz.openbmc_project.Association", "endpoints",
292cf7eba09SNan Zhou                 [asyncResp, chassisId](const boost::system::error_code ec3,
29392903bd4SJohn Edward Broadbent                                        const std::vector<std::string>& resp) {
29492903bd4SJohn Edward Broadbent                 if (ec3 || resp.empty())
29592903bd4SJohn Edward Broadbent                 {
29692903bd4SJohn Edward Broadbent                     return; // no drives = no failures
29792903bd4SJohn Edward Broadbent                 }
29892903bd4SJohn Edward Broadbent 
29992903bd4SJohn Edward Broadbent                 nlohmann::json reference;
300a0cb40cbSJohn Edward Broadbent                 reference["@odata.id"] = crow::utility::urlFromPieces(
30192903bd4SJohn Edward Broadbent                     "redfish", "v1", "Chassis", chassisId, "Drives");
30292903bd4SJohn Edward Broadbent                 asyncResp->res.jsonValue["Drives"] = std::move(reference);
30392903bd4SJohn Edward Broadbent                 });
30492903bd4SJohn Edward Broadbent 
305002d39b4SEd Tanous             const std::string& connectionName = connectionNames[0].first;
3061c8fba97SJames Feist 
30723a21a1cSEd Tanous             const std::vector<std::string>& interfaces2 =
3081c8fba97SJames Feist                 connectionNames[0].second;
3091c8fba97SJames Feist             const std::array<const char*, 2> hasIndicatorLed = {
3101c8fba97SJames Feist                 "xyz.openbmc_project.Inventory.Item.Panel",
3110fda0f12SGeorge Liu                 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
3121c8fba97SJames Feist 
313476b9cc5STejas Patil             const std::string assetTagInterface =
3140fda0f12SGeorge Liu                 "xyz.openbmc_project.Inventory.Decorator.AssetTag";
315476b9cc5STejas Patil             if (std::find(interfaces2.begin(), interfaces2.end(),
316476b9cc5STejas Patil                           assetTagInterface) != interfaces2.end())
317476b9cc5STejas Patil             {
3181e1e598dSJonathan Doman                 sdbusplus::asio::getProperty<std::string>(
319002d39b4SEd Tanous                     *crow::connections::systemBus, connectionName, path,
320002d39b4SEd Tanous                     assetTagInterface, "AssetTag",
321476b9cc5STejas Patil                     [asyncResp, chassisId(std::string(chassisId))](
3228a592810SEd Tanous                         const boost::system::error_code ec2,
3231e1e598dSJonathan Doman                         const std::string& property) {
3248a592810SEd Tanous                     if (ec2)
325476b9cc5STejas Patil                     {
326cf7eba09SNan Zhou                         BMCWEB_LOG_DEBUG << "DBus response error for AssetTag";
327476b9cc5STejas Patil                         messages::internalError(asyncResp->res);
328476b9cc5STejas Patil                         return;
329476b9cc5STejas Patil                     }
330002d39b4SEd Tanous                     asyncResp->res.jsonValue["AssetTag"] = property;
3311e1e598dSJonathan Doman                     });
332476b9cc5STejas Patil             }
333476b9cc5STejas Patil 
3341c8fba97SJames Feist             for (const char* interface : hasIndicatorLed)
3351c8fba97SJames Feist             {
336002d39b4SEd Tanous                 if (std::find(interfaces2.begin(), interfaces2.end(),
33723a21a1cSEd Tanous                               interface) != interfaces2.end())
3381c8fba97SJames Feist                 {
3391c8fba97SJames Feist                     getIndicatorLedState(asyncResp);
3409f8bfa7cSGunnar Mills                     getLocationIndicatorActive(asyncResp);
3411c8fba97SJames Feist                     break;
3421c8fba97SJames Feist                 }
3431c8fba97SJames Feist             }
3441c8fba97SJames Feist 
34586d89ed7SKrzysztof Grobelny             sdbusplus::asio::getAllProperties(
34686d89ed7SKrzysztof Grobelny                 *crow::connections::systemBus, connectionName, path,
34786d89ed7SKrzysztof Grobelny                 "xyz.openbmc_project.Inventory.Decorator.Asset",
34862d5e2e4SEd Tanous                 [asyncResp, chassisId(std::string(chassisId))](
34990728b54SEd Tanous                     const boost::system::error_code /*ec2*/,
350cf7eba09SNan Zhou                     const dbus::utility::DBusPropertiesMap& propertiesList) {
35186d89ed7SKrzysztof Grobelny                 const std::string* partNumber = nullptr;
35286d89ed7SKrzysztof Grobelny                 const std::string* serialNumber = nullptr;
35386d89ed7SKrzysztof Grobelny                 const std::string* manufacturer = nullptr;
35486d89ed7SKrzysztof Grobelny                 const std::string* model = nullptr;
35586d89ed7SKrzysztof Grobelny                 const std::string* sparePartNumber = nullptr;
35686d89ed7SKrzysztof Grobelny 
35786d89ed7SKrzysztof Grobelny                 const bool success = sdbusplus::unpackPropertiesNoThrow(
35886d89ed7SKrzysztof Grobelny                     dbus_utils::UnpackErrorPrinter(), propertiesList,
35986d89ed7SKrzysztof Grobelny                     "PartNumber", partNumber, "SerialNumber", serialNumber,
36086d89ed7SKrzysztof Grobelny                     "Manufacturer", manufacturer, "Model", model,
36186d89ed7SKrzysztof Grobelny                     "SparePartNumber", sparePartNumber);
36286d89ed7SKrzysztof Grobelny 
36386d89ed7SKrzysztof Grobelny                 if (!success)
3641abe55efSEd Tanous                 {
365002d39b4SEd Tanous                     messages::internalError(asyncResp->res);
366caa11f7aSAlpana Kumari                     return;
367daf36e2eSEd Tanous                 }
36886d89ed7SKrzysztof Grobelny 
36986d89ed7SKrzysztof Grobelny                 if (partNumber != nullptr)
37086d89ed7SKrzysztof Grobelny                 {
37186d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["PartNumber"] = *partNumber;
37286d89ed7SKrzysztof Grobelny                 }
37386d89ed7SKrzysztof Grobelny 
37486d89ed7SKrzysztof Grobelny                 if (serialNumber != nullptr)
37586d89ed7SKrzysztof Grobelny                 {
37686d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
37786d89ed7SKrzysztof Grobelny                 }
37886d89ed7SKrzysztof Grobelny 
37986d89ed7SKrzysztof Grobelny                 if (manufacturer != nullptr)
38086d89ed7SKrzysztof Grobelny                 {
38186d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
38286d89ed7SKrzysztof Grobelny                 }
38386d89ed7SKrzysztof Grobelny 
38486d89ed7SKrzysztof Grobelny                 if (model != nullptr)
38586d89ed7SKrzysztof Grobelny                 {
38686d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["Model"] = *model;
38786d89ed7SKrzysztof Grobelny                 }
38886d89ed7SKrzysztof Grobelny 
389caa11f7aSAlpana Kumari                 // SparePartNumber is optional on D-Bus
390caa11f7aSAlpana Kumari                 // so skip if it is empty
39186d89ed7SKrzysztof Grobelny                 if (sparePartNumber != nullptr && !sparePartNumber->empty())
392caa11f7aSAlpana Kumari                 {
39386d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["SparePartNumber"] =
39486d89ed7SKrzysztof Grobelny                         *sparePartNumber;
395caa11f7aSAlpana Kumari                 }
39686d89ed7SKrzysztof Grobelny 
39762d5e2e4SEd Tanous                 asyncResp->res.jsonValue["Name"] = chassisId;
39862d5e2e4SEd Tanous                 asyncResp->res.jsonValue["Id"] = chassisId;
3990256b694Szhanghch05 #ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL
400002d39b4SEd Tanous                 asyncResp->res.jsonValue["Thermal"]["@odata.id"] =
401002d39b4SEd Tanous                     "/redfish/v1/Chassis/" + chassisId + "/Thermal";
4022474adfaSEd Tanous                 // Power object
4031476687dSEd Tanous                 asyncResp->res.jsonValue["Power"]["@odata.id"] =
404002d39b4SEd Tanous                     "/redfish/v1/Chassis/" + chassisId + "/Power";
4050256b694Szhanghch05 #endif
4062973963eSXiaochao Ma #ifdef BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM
4072973963eSXiaochao Ma                 asyncResp->res.jsonValue["ThermalSubsystem"]["@odata.id"] =
4082973963eSXiaochao Ma                     crow::utility::urlFromPieces("redfish", "v1", "Chassis",
4092973963eSXiaochao Ma                                                  chassisId, "ThermalSubsystem");
41077b36437SChicago Duan                 asyncResp->res.jsonValue["PowerSubsystem"]["@odata.id"] =
41177b36437SChicago Duan                     crow::utility::urlFromPieces("redfish", "v1", "Chassis",
41277b36437SChicago Duan                                                  chassisId, "PowerSubsystem");
4134ca3ec3cSAlbert Zhang                 asyncResp->res.jsonValue["EnvironmentMetrics"]["@odata.id"] =
4144ca3ec3cSAlbert Zhang                     crow::utility::urlFromPieces("redfish", "v1", "Chassis",
4154ca3ec3cSAlbert Zhang                                                  chassisId,
4164ca3ec3cSAlbert Zhang                                                  "EnvironmentMetrics");
4172973963eSXiaochao Ma #endif
41895a3ecadSAnthony Wilson                 // SensorCollection
419002d39b4SEd Tanous                 asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
420002d39b4SEd Tanous                     "/redfish/v1/Chassis/" + chassisId + "/Sensors";
421002d39b4SEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
4221476687dSEd Tanous 
4231476687dSEd Tanous                 nlohmann::json::array_t computerSystems;
4241476687dSEd Tanous                 nlohmann::json::object_t system;
425002d39b4SEd Tanous                 system["@odata.id"] = "/redfish/v1/Systems/system";
4261476687dSEd Tanous                 computerSystems.push_back(std::move(system));
427002d39b4SEd Tanous                 asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
4281476687dSEd Tanous                     std::move(computerSystems);
4291476687dSEd Tanous 
4301476687dSEd Tanous                 nlohmann::json::array_t managedBy;
4311476687dSEd Tanous                 nlohmann::json::object_t manager;
432002d39b4SEd Tanous                 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
4331476687dSEd Tanous                 managedBy.push_back(std::move(manager));
4347e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["Links"]["ManagedBy"] =
4351476687dSEd Tanous                     std::move(managedBy);
436beeca0aeSGunnar Mills                 getChassisState(asyncResp);
43786d89ed7SKrzysztof Grobelny                 });
4382c37b4b0SSharad Yadav 
439308f70c7SWilly Tu             for (const auto& interface : interfaces2)
4402c37b4b0SSharad Yadav             {
441308f70c7SWilly Tu                 if (interface == "xyz.openbmc_project.Common.UUID")
4422c37b4b0SSharad Yadav                 {
443308f70c7SWilly Tu                     getChassisUUID(asyncResp, connectionName, path);
4442c37b4b0SSharad Yadav                 }
445cf7eba09SNan Zhou                 else if (interface ==
4460fda0f12SGeorge Liu                          "xyz.openbmc_project.Inventory.Decorator.LocationCode")
4472c37b4b0SSharad Yadav                 {
448002d39b4SEd Tanous                     getChassisLocationCode(asyncResp, connectionName, path);
4492c37b4b0SSharad Yadav                 }
4502c37b4b0SSharad Yadav             }
4512c37b4b0SSharad Yadav 
452daf36e2eSEd Tanous             return;
453daf36e2eSEd Tanous         }
454e0d918bcSEd Tanous 
455daf36e2eSEd Tanous         // Couldn't find an object with that name.  return an error
456d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
457daf36e2eSEd Tanous         },
458daf36e2eSEd Tanous         "xyz.openbmc_project.ObjectMapper",
459daf36e2eSEd Tanous         "/xyz/openbmc_project/object_mapper",
460daf36e2eSEd Tanous         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
461271584abSEd Tanous         "/xyz/openbmc_project/inventory", 0, interfaces);
462c181942fSQiang XU 
463c181942fSQiang XU     getPhysicalSecurityData(asyncResp);
464cf7eba09SNan Zhou }
4651c8fba97SJames Feist 
466cf7eba09SNan Zhou inline void
467cf7eba09SNan Zhou     handleChassisPatch(App& app, const crow::Request& req,
4687e860f15SJohn Edward Broadbent                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
469cf7eba09SNan Zhou                        const std::string& param)
470cf7eba09SNan Zhou {
4713ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
47245ca1b86SEd Tanous     {
47345ca1b86SEd Tanous         return;
47445ca1b86SEd Tanous     }
4759f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
4761c8fba97SJames Feist     std::optional<std::string> indicatorLed;
4771c8fba97SJames Feist 
4787e860f15SJohn Edward Broadbent     if (param.empty())
4791c8fba97SJames Feist     {
4801c8fba97SJames Feist         return;
4811c8fba97SJames Feist     }
4821c8fba97SJames Feist 
48315ed6780SWilly Tu     if (!json_util::readJsonPatch(
4847e860f15SJohn Edward Broadbent             req, asyncResp->res, "LocationIndicatorActive",
4857e860f15SJohn Edward Broadbent             locationIndicatorActive, "IndicatorLED", indicatorLed))
4861c8fba97SJames Feist     {
4871c8fba97SJames Feist         return;
4881c8fba97SJames Feist     }
4891c8fba97SJames Feist 
4909f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
4919f8bfa7cSGunnar Mills     if (!locationIndicatorActive && !indicatorLed)
4921c8fba97SJames Feist     {
4931c8fba97SJames Feist         return; // delete this when we support more patch properties
4941c8fba97SJames Feist     }
495d6aa0093SGunnar Mills     if (indicatorLed)
496d6aa0093SGunnar Mills     {
4977e860f15SJohn Edward Broadbent         asyncResp->res.addHeader(
4987e860f15SJohn Edward Broadbent             boost::beast::http::field::warning,
4990fda0f12SGeorge Liu             "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
500d6aa0093SGunnar Mills     }
5011c8fba97SJames Feist 
5021c8fba97SJames Feist     const std::array<const char*, 2> interfaces = {
5031c8fba97SJames Feist         "xyz.openbmc_project.Inventory.Item.Board",
5041c8fba97SJames Feist         "xyz.openbmc_project.Inventory.Item.Chassis"};
5051c8fba97SJames Feist 
5067e860f15SJohn Edward Broadbent     const std::string& chassisId = param;
5071c8fba97SJames Feist 
5081c8fba97SJames Feist     crow::connections::systemBus->async_method_call(
509cf7eba09SNan Zhou         [asyncResp, chassisId, locationIndicatorActive,
510cf7eba09SNan Zhou          indicatorLed](const boost::system::error_code ec,
511b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
5121c8fba97SJames Feist         if (ec)
5131c8fba97SJames Feist         {
5141c8fba97SJames Feist             messages::internalError(asyncResp->res);
5151c8fba97SJames Feist             return;
5161c8fba97SJames Feist         }
5171c8fba97SJames Feist 
5181c8fba97SJames Feist         // Iterate over all retrieved ObjectPaths.
519cf7eba09SNan Zhou         for (const std::pair<
520cf7eba09SNan Zhou                  std::string,
521cf7eba09SNan Zhou                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
5221214b7e7SGunnar Mills                  object : subtree)
5231c8fba97SJames Feist         {
5241c8fba97SJames Feist             const std::string& path = object.first;
525cf7eba09SNan Zhou             const std::vector<std::pair<std::string, std::vector<std::string>>>&
5261214b7e7SGunnar Mills                 connectionNames = object.second;
5271c8fba97SJames Feist 
528997093ebSGeorge Liu             sdbusplus::message::object_path objPath(path);
529997093ebSGeorge Liu             if (objPath.filename() != chassisId)
5301c8fba97SJames Feist             {
5311c8fba97SJames Feist                 continue;
5321c8fba97SJames Feist             }
5331c8fba97SJames Feist 
53426f6976fSEd Tanous             if (connectionNames.empty())
5351c8fba97SJames Feist             {
5361c8fba97SJames Feist                 BMCWEB_LOG_ERROR << "Got 0 Connection names";
5371c8fba97SJames Feist                 continue;
5381c8fba97SJames Feist             }
5391c8fba97SJames Feist 
54023a21a1cSEd Tanous             const std::vector<std::string>& interfaces3 =
5411c8fba97SJames Feist                 connectionNames[0].second;
5421c8fba97SJames Feist 
5431c8fba97SJames Feist             const std::array<const char*, 2> hasIndicatorLed = {
5441c8fba97SJames Feist                 "xyz.openbmc_project.Inventory.Item.Panel",
5450fda0f12SGeorge Liu                 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
5461c8fba97SJames Feist             bool indicatorChassis = false;
5471c8fba97SJames Feist             for (const char* interface : hasIndicatorLed)
5481c8fba97SJames Feist             {
549002d39b4SEd Tanous                 if (std::find(interfaces3.begin(), interfaces3.end(),
55023a21a1cSEd Tanous                               interface) != interfaces3.end())
5511c8fba97SJames Feist                 {
5521c8fba97SJames Feist                     indicatorChassis = true;
5531c8fba97SJames Feist                     break;
5541c8fba97SJames Feist                 }
5551c8fba97SJames Feist             }
5569f8bfa7cSGunnar Mills             if (locationIndicatorActive)
5579f8bfa7cSGunnar Mills             {
5589f8bfa7cSGunnar Mills                 if (indicatorChassis)
5599f8bfa7cSGunnar Mills                 {
560002d39b4SEd Tanous                     setLocationIndicatorActive(asyncResp,
561002d39b4SEd Tanous                                                *locationIndicatorActive);
5629f8bfa7cSGunnar Mills                 }
5639f8bfa7cSGunnar Mills                 else
5649f8bfa7cSGunnar Mills                 {
565002d39b4SEd Tanous                     messages::propertyUnknown(asyncResp->res,
566002d39b4SEd Tanous                                               "LocationIndicatorActive");
5679f8bfa7cSGunnar Mills                 }
5689f8bfa7cSGunnar Mills             }
5699f8bfa7cSGunnar Mills             if (indicatorLed)
5709f8bfa7cSGunnar Mills             {
5711c8fba97SJames Feist                 if (indicatorChassis)
5721c8fba97SJames Feist                 {
573f23b7296SEd Tanous                     setIndicatorLedState(asyncResp, *indicatorLed);
5741c8fba97SJames Feist                 }
5751c8fba97SJames Feist                 else
5761c8fba97SJames Feist                 {
577cf7eba09SNan Zhou                     messages::propertyUnknown(asyncResp->res, "IndicatorLED");
5781c8fba97SJames Feist                 }
5791c8fba97SJames Feist             }
5801c8fba97SJames Feist             return;
5811c8fba97SJames Feist         }
5821c8fba97SJames Feist 
583d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
5841c8fba97SJames Feist         },
5851c8fba97SJames Feist         "xyz.openbmc_project.ObjectMapper",
5861c8fba97SJames Feist         "/xyz/openbmc_project/object_mapper",
5871c8fba97SJames Feist         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5881c8fba97SJames Feist         "/xyz/openbmc_project/inventory", 0, interfaces);
589cf7eba09SNan Zhou }
590cf7eba09SNan Zhou 
591cf7eba09SNan Zhou /**
592cf7eba09SNan Zhou  * Chassis override class for delivering Chassis Schema
593cf7eba09SNan Zhou  * Functions triggers appropriate requests on DBus
594cf7eba09SNan Zhou  */
595cf7eba09SNan Zhou inline void requestRoutesChassis(App& app)
596cf7eba09SNan Zhou {
597cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
598cf7eba09SNan Zhou         .privileges(redfish::privileges::getChassis)
599cf7eba09SNan Zhou         .methods(boost::beast::http::verb::get)(
600cf7eba09SNan Zhou             std::bind_front(handleChassisGet, std::ref(app)));
601cf7eba09SNan Zhou 
602cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
603cf7eba09SNan Zhou         .privileges(redfish::privileges::patchChassis)
604cf7eba09SNan Zhou         .methods(boost::beast::http::verb::patch)(
605cf7eba09SNan Zhou             std::bind_front(handleChassisPatch, std::ref(app)));
6061c8fba97SJames Feist }
607dd99e04bSP.K. Lee 
6088d1b46d7Szhanghch05 inline void
6098d1b46d7Szhanghch05     doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
610dd99e04bSP.K. Lee {
6117a1dbc48SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
612c3b3c92aSVijay Khemka         "xyz.openbmc_project.State.Chassis"};
613c3b3c92aSVijay Khemka 
614c3b3c92aSVijay Khemka     // Use mapper to get subtree paths.
6157a1dbc48SGeorge Liu     dbus::utility::getSubTreePaths(
6167a1dbc48SGeorge Liu         "/", 0, interfaces,
617b9d36b47SEd Tanous         [asyncResp](
6187a1dbc48SGeorge Liu             const boost::system::error_code& ec,
619b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreePathsResponse& chassisList) {
620c3b3c92aSVijay Khemka         if (ec)
621c3b3c92aSVijay Khemka         {
622c3b3c92aSVijay Khemka             BMCWEB_LOG_DEBUG << "[mapper] Bad D-Bus request error: " << ec;
623c3b3c92aSVijay Khemka             messages::internalError(asyncResp->res);
624c3b3c92aSVijay Khemka             return;
625c3b3c92aSVijay Khemka         }
626c3b3c92aSVijay Khemka 
627dd99e04bSP.K. Lee         const char* processName = "xyz.openbmc_project.State.Chassis";
628dd99e04bSP.K. Lee         const char* interfaceName = "xyz.openbmc_project.State.Chassis";
629dd99e04bSP.K. Lee         const char* destProperty = "RequestedPowerTransition";
630dd99e04bSP.K. Lee         const std::string propertyValue =
631dd99e04bSP.K. Lee             "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
632002d39b4SEd Tanous         std::string objectPath = "/xyz/openbmc_project/state/chassis_system0";
633c3b3c92aSVijay Khemka 
634c3b3c92aSVijay Khemka         /* Look for system reset chassis path */
635002d39b4SEd Tanous         if ((std::find(chassisList.begin(), chassisList.end(), objectPath)) ==
636002d39b4SEd Tanous             chassisList.end())
637c3b3c92aSVijay Khemka         {
638c3b3c92aSVijay Khemka             /* We prefer to reset the full chassis_system, but if it doesn't
639c3b3c92aSVijay Khemka              * exist on some platforms, fall back to a host-only power reset
640c3b3c92aSVijay Khemka              */
641c3b3c92aSVijay Khemka             objectPath = "/xyz/openbmc_project/state/chassis0";
642c3b3c92aSVijay Khemka         }
643dd99e04bSP.K. Lee 
644dd99e04bSP.K. Lee         crow::connections::systemBus->async_method_call(
6458a592810SEd Tanous             [asyncResp](const boost::system::error_code ec2) {
646dd99e04bSP.K. Lee             // Use "Set" method to set the property value.
6478a592810SEd Tanous             if (ec2)
648dd99e04bSP.K. Lee             {
6498a592810SEd Tanous                 BMCWEB_LOG_DEBUG << "[Set] Bad D-Bus request error: " << ec2;
650dd99e04bSP.K. Lee                 messages::internalError(asyncResp->res);
651dd99e04bSP.K. Lee                 return;
652dd99e04bSP.K. Lee             }
653dd99e04bSP.K. Lee 
654dd99e04bSP.K. Lee             messages::success(asyncResp->res);
655dd99e04bSP.K. Lee             },
656002d39b4SEd Tanous             processName, objectPath, "org.freedesktop.DBus.Properties", "Set",
657002d39b4SEd Tanous             interfaceName, destProperty,
658168e20c1SEd Tanous             dbus::utility::DbusVariantType{propertyValue});
6597a1dbc48SGeorge Liu         });
660dd99e04bSP.K. Lee }
661dd99e04bSP.K. Lee 
662cf7eba09SNan Zhou inline void handleChassisResetActionInfoPost(
663cf7eba09SNan Zhou     App& app, const crow::Request& req,
6647e860f15SJohn Edward Broadbent     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
665cf7eba09SNan Zhou     const std::string& /*chassisId*/)
666cf7eba09SNan Zhou {
6673ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
66845ca1b86SEd Tanous     {
66945ca1b86SEd Tanous         return;
67045ca1b86SEd Tanous     }
671dd99e04bSP.K. Lee     BMCWEB_LOG_DEBUG << "Post Chassis Reset.";
672dd99e04bSP.K. Lee 
673dd99e04bSP.K. Lee     std::string resetType;
674dd99e04bSP.K. Lee 
675cf7eba09SNan Zhou     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
676dd99e04bSP.K. Lee     {
677dd99e04bSP.K. Lee         return;
678dd99e04bSP.K. Lee     }
679dd99e04bSP.K. Lee 
680dd99e04bSP.K. Lee     if (resetType != "PowerCycle")
681dd99e04bSP.K. Lee     {
682dd99e04bSP.K. Lee         BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
683dd99e04bSP.K. Lee                          << resetType;
684002d39b4SEd Tanous         messages::actionParameterNotSupported(asyncResp->res, resetType,
685002d39b4SEd Tanous                                               "ResetType");
686dd99e04bSP.K. Lee 
687dd99e04bSP.K. Lee         return;
688dd99e04bSP.K. Lee     }
689dd99e04bSP.K. Lee     doChassisPowerCycle(asyncResp);
690dd99e04bSP.K. Lee }
6911cb1a9e6SAppaRao Puli 
6921cb1a9e6SAppaRao Puli /**
693cf7eba09SNan Zhou  * ChassisResetAction class supports the POST method for the Reset
694cf7eba09SNan Zhou  * action.
695cf7eba09SNan Zhou  * Function handles POST method request.
696cf7eba09SNan Zhou  * Analyzes POST body before sending Reset request data to D-Bus.
6971cb1a9e6SAppaRao Puli  */
698cf7eba09SNan Zhou 
699cf7eba09SNan Zhou inline void requestRoutesChassisResetAction(App& app)
7001cb1a9e6SAppaRao Puli {
701cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/")
702cf7eba09SNan Zhou         .privileges(redfish::privileges::postChassis)
703cf7eba09SNan Zhou         .methods(boost::beast::http::verb::post)(
704cf7eba09SNan Zhou             std::bind_front(handleChassisResetActionInfoPost, std::ref(app)));
705cf7eba09SNan Zhou }
706cf7eba09SNan Zhou 
707cf7eba09SNan Zhou inline void handleChassisResetActionInfoGet(
708cf7eba09SNan Zhou     App& app, const crow::Request& req,
7097e860f15SJohn Edward Broadbent     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
710cf7eba09SNan Zhou     const std::string& chassisId)
711cf7eba09SNan Zhou {
7123ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
7131cb1a9e6SAppaRao Puli     {
71445ca1b86SEd Tanous         return;
71545ca1b86SEd Tanous     }
716cf7eba09SNan Zhou     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
7171476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
7181476687dSEd Tanous         "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
7191476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
7201476687dSEd Tanous 
7211476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
7225b9e95a1SNan Zhou     nlohmann::json::array_t parameters;
7235b9e95a1SNan Zhou     nlohmann::json::object_t parameter;
7245b9e95a1SNan Zhou     parameter["Name"] = "ResetType";
7255b9e95a1SNan Zhou     parameter["Required"] = true;
7265b9e95a1SNan Zhou     parameter["DataType"] = "String";
7271476687dSEd Tanous     nlohmann::json::array_t allowed;
7281476687dSEd Tanous     allowed.push_back("PowerCycle");
7295b9e95a1SNan Zhou     parameter["AllowableValues"] = std::move(allowed);
7305b9e95a1SNan Zhou     parameters.push_back(std::move(parameter));
7315b9e95a1SNan Zhou 
7321476687dSEd Tanous     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
733cf7eba09SNan Zhou }
734cf7eba09SNan Zhou 
735cf7eba09SNan Zhou /**
736cf7eba09SNan Zhou  * ChassisResetActionInfo derived class for delivering Chassis
737cf7eba09SNan Zhou  * ResetType AllowableValues using ResetInfo schema.
738cf7eba09SNan Zhou  */
739cf7eba09SNan Zhou inline void requestRoutesChassisResetActionInfo(App& app)
740cf7eba09SNan Zhou {
741cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/")
742cf7eba09SNan Zhou         .privileges(redfish::privileges::getActionInfo)
743cf7eba09SNan Zhou         .methods(boost::beast::http::verb::get)(
744cf7eba09SNan Zhou             std::bind_front(handleChassisResetActionInfoGet, std::ref(app)));
7451cb1a9e6SAppaRao Puli }
7461cb1a9e6SAppaRao Puli 
747e37f8451SRapkiewicz, Pawel } // namespace redfish
748