xref: /openbmc/bmcweb/features/redfish/lib/chassis.hpp (revision ef4c65b741724d724452a3a0efe8dff0d450514a)
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