xref: /openbmc/bmcweb/features/redfish/lib/chassis.hpp (revision 86d89ed7ad605b0f7dbe2c11200363fd34c6364c)
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 
18b49ac873SJames Feist #include "health.hpp"
191c8fba97SJames Feist #include "led.hpp"
20cf7eba09SNan Zhou #include "utils/json_utils.hpp"
211abe55efSEd Tanous 
227e860f15SJohn Edward Broadbent #include <app.hpp>
23168e20c1SEd Tanous #include <dbus_utility.hpp>
2445ca1b86SEd Tanous #include <query.hpp>
25ed398213SEd Tanous #include <registries/privilege_registry.hpp>
261e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
27*86d89ed7SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
2802f6ff19SGunnar Mills #include <utils/collection.hpp>
29*86d89ed7SKrzysztof Grobelny #include <utils/dbus_utils.hpp>
301214b7e7SGunnar Mills 
311abe55efSEd Tanous namespace redfish
321abe55efSEd Tanous {
33e37f8451SRapkiewicz, Pawel 
34e37f8451SRapkiewicz, Pawel /**
35beeca0aeSGunnar Mills  * @brief Retrieves chassis state properties over dbus
36beeca0aeSGunnar Mills  *
37beeca0aeSGunnar Mills  * @param[in] aResp - Shared pointer for completing asynchronous calls.
38beeca0aeSGunnar Mills  *
39beeca0aeSGunnar Mills  * @return None.
40beeca0aeSGunnar Mills  */
418d1b46d7Szhanghch05 inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> aResp)
42beeca0aeSGunnar Mills {
431e1e598dSJonathan Doman     // crow::connections::systemBus->async_method_call(
441e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
451e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
461e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
471e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "CurrentPowerState",
481e1e598dSJonathan Doman         [aResp{std::move(aResp)}](const boost::system::error_code ec,
491e1e598dSJonathan Doman                                   const std::string& chassisState) {
50beeca0aeSGunnar Mills         if (ec)
51beeca0aeSGunnar Mills         {
52a6e5e0abSCarson Labrado             if (ec == boost::system::errc::host_unreachable)
53a6e5e0abSCarson Labrado             {
54a6e5e0abSCarson Labrado                 // Service not available, no error, just don't return
55a6e5e0abSCarson Labrado                 // chassis state info
56a6e5e0abSCarson Labrado                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
57a6e5e0abSCarson Labrado                 return;
58a6e5e0abSCarson Labrado             }
59beeca0aeSGunnar Mills             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
60beeca0aeSGunnar Mills             messages::internalError(aResp->res);
61beeca0aeSGunnar Mills             return;
62beeca0aeSGunnar Mills         }
63beeca0aeSGunnar Mills 
641e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Chassis state: " << chassisState;
65beeca0aeSGunnar Mills         // Verify Chassis State
66002d39b4SEd Tanous         if (chassisState == "xyz.openbmc_project.State.Chassis.PowerState.On")
67beeca0aeSGunnar Mills         {
68beeca0aeSGunnar Mills             aResp->res.jsonValue["PowerState"] = "On";
69beeca0aeSGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "Enabled";
70beeca0aeSGunnar Mills         }
711e1e598dSJonathan Doman         else if (chassisState ==
72beeca0aeSGunnar Mills                  "xyz.openbmc_project.State.Chassis.PowerState.Off")
73beeca0aeSGunnar Mills         {
74beeca0aeSGunnar Mills             aResp->res.jsonValue["PowerState"] = "Off";
75beeca0aeSGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "StandbyOffline";
76beeca0aeSGunnar Mills         }
771e1e598dSJonathan Doman         });
78beeca0aeSGunnar Mills }
79beeca0aeSGunnar Mills 
808d1b46d7Szhanghch05 inline void getIntrusionByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
81c181942fSQiang XU                                   const std::string& service,
82c181942fSQiang XU                                   const std::string& objPath)
83c181942fSQiang XU {
84c181942fSQiang XU     BMCWEB_LOG_DEBUG << "Get intrusion status by service \n";
85c181942fSQiang XU 
861e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
871e1e598dSJonathan Doman         *crow::connections::systemBus, service, objPath,
881e1e598dSJonathan Doman         "xyz.openbmc_project.Chassis.Intrusion", "Status",
89c181942fSQiang XU         [aResp{std::move(aResp)}](const boost::system::error_code ec,
901e1e598dSJonathan Doman                                   const std::string& value) {
91c181942fSQiang XU         if (ec)
92c181942fSQiang XU         {
934e0453b1SGunnar Mills             // do not add err msg in redfish response, because this is not
94c181942fSQiang XU             //     mandatory property
95c181942fSQiang XU             BMCWEB_LOG_ERROR << "DBUS response error " << ec << "\n";
96c181942fSQiang XU             return;
97c181942fSQiang XU         }
98c181942fSQiang XU 
99002d39b4SEd Tanous         aResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensorNumber"] = 1;
1001476687dSEd Tanous         aResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensor"] = value;
1011e1e598dSJonathan Doman         });
102c181942fSQiang XU }
103c181942fSQiang XU 
104c181942fSQiang XU /**
105c181942fSQiang XU  * Retrieves physical security properties over dbus
106c181942fSQiang XU  */
1078d1b46d7Szhanghch05 inline void getPhysicalSecurityData(std::shared_ptr<bmcweb::AsyncResp> aResp)
108c181942fSQiang XU {
109c181942fSQiang XU     crow::connections::systemBus->async_method_call(
110c181942fSQiang XU         [aResp{std::move(aResp)}](
111c181942fSQiang XU             const boost::system::error_code ec,
112b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
113c181942fSQiang XU         if (ec)
114c181942fSQiang XU         {
1154e0453b1SGunnar Mills             // do not add err msg in redfish response, because this is not
116c181942fSQiang XU             //     mandatory property
117002d39b4SEd Tanous             BMCWEB_LOG_INFO << "DBUS error: no matched iface " << ec << "\n";
118c181942fSQiang XU             return;
119c181942fSQiang XU         }
120c181942fSQiang XU         // Iterate over all retrieved ObjectPaths.
121c181942fSQiang XU         for (const auto& object : subtree)
122c181942fSQiang XU         {
123c181942fSQiang XU             for (const auto& service : object.second)
124c181942fSQiang XU             {
125c181942fSQiang XU                 getIntrusionByService(aResp, service.first, object.first);
126c181942fSQiang XU                 return;
127c181942fSQiang XU             }
128c181942fSQiang XU         }
129c181942fSQiang XU         },
130c181942fSQiang XU         "xyz.openbmc_project.ObjectMapper",
131c181942fSQiang XU         "/xyz/openbmc_project/object_mapper",
132c181942fSQiang XU         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
133271584abSEd Tanous         "/xyz/openbmc_project/Intrusion", 1,
134c181942fSQiang XU         std::array<const char*, 1>{"xyz.openbmc_project.Chassis.Intrusion"});
135c181942fSQiang XU }
136c181942fSQiang XU 
137cf7eba09SNan Zhou inline void handleChassisCollectionGet(
138cf7eba09SNan Zhou     App& app, const crow::Request& req,
139cf7eba09SNan Zhou     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1401abe55efSEd Tanous {
1413ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
14245ca1b86SEd Tanous     {
14345ca1b86SEd Tanous         return;
14445ca1b86SEd Tanous     }
1458d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
1468d1b46d7Szhanghch05         "#ChassisCollection.ChassisCollection";
1478d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
1488d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Chassis Collection";
149e37f8451SRapkiewicz, Pawel 
15002f6ff19SGunnar Mills     collection_util::getCollectionMembers(
15102f6ff19SGunnar Mills         asyncResp, "/redfish/v1/Chassis",
15202f6ff19SGunnar Mills         {"xyz.openbmc_project.Inventory.Item.Board",
15302f6ff19SGunnar Mills          "xyz.openbmc_project.Inventory.Item.Chassis"});
154cf7eba09SNan Zhou }
155cf7eba09SNan Zhou 
156cf7eba09SNan Zhou /**
157cf7eba09SNan Zhou  * ChassisCollection derived class for delivering Chassis Collection Schema
158cf7eba09SNan Zhou  *  Functions triggers appropriate requests on DBus
159cf7eba09SNan Zhou  */
160cf7eba09SNan Zhou inline void requestRoutesChassisCollection(App& app)
161cf7eba09SNan Zhou {
162cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/")
163cf7eba09SNan Zhou         .privileges(redfish::privileges::getChassisCollection)
164cf7eba09SNan Zhou         .methods(boost::beast::http::verb::get)(
165cf7eba09SNan Zhou             std::bind_front(handleChassisCollectionGet, std::ref(app)));
16662d5e2e4SEd Tanous }
167e37f8451SRapkiewicz, Pawel 
168308f70c7SWilly Tu inline void
169308f70c7SWilly Tu     getChassisLocationCode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
170308f70c7SWilly Tu                            const std::string& connectionName,
171308f70c7SWilly Tu                            const std::string& path)
172308f70c7SWilly Tu {
1731e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
1741e1e598dSJonathan Doman         *crow::connections::systemBus, connectionName, path,
1751e1e598dSJonathan Doman         "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
176308f70c7SWilly Tu         [asyncResp](const boost::system::error_code ec,
1771e1e598dSJonathan Doman                     const std::string& property) {
178308f70c7SWilly Tu         if (ec)
179308f70c7SWilly Tu         {
1800fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error for Location";
181308f70c7SWilly Tu             messages::internalError(asyncResp->res);
182308f70c7SWilly Tu             return;
183308f70c7SWilly Tu         }
184308f70c7SWilly Tu 
185002d39b4SEd Tanous         asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
1861e1e598dSJonathan Doman             property;
1871e1e598dSJonathan Doman         });
188308f70c7SWilly Tu }
189308f70c7SWilly Tu 
190308f70c7SWilly Tu inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
191308f70c7SWilly Tu                            const std::string& connectionName,
192308f70c7SWilly Tu                            const std::string& path)
193308f70c7SWilly Tu {
1941e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
1951e1e598dSJonathan Doman         *crow::connections::systemBus, connectionName, path,
1961e1e598dSJonathan Doman         "xyz.openbmc_project.Common.UUID", "UUID",
197308f70c7SWilly Tu         [asyncResp](const boost::system::error_code ec,
1981e1e598dSJonathan Doman                     const std::string& chassisUUID) {
199308f70c7SWilly Tu         if (ec)
200308f70c7SWilly Tu         {
2010fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error for UUID";
202308f70c7SWilly Tu             messages::internalError(asyncResp->res);
203308f70c7SWilly Tu             return;
204308f70c7SWilly Tu         }
2051e1e598dSJonathan Doman         asyncResp->res.jsonValue["UUID"] = chassisUUID;
2061e1e598dSJonathan Doman         });
207308f70c7SWilly Tu }
208308f70c7SWilly Tu 
209cf7eba09SNan Zhou inline void
210cf7eba09SNan Zhou     handleChassisGet(App& app, const crow::Request& req,
21145ca1b86SEd Tanous                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
212cf7eba09SNan Zhou                      const std::string& chassisId)
213cf7eba09SNan Zhou {
2143ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
21545ca1b86SEd Tanous     {
21645ca1b86SEd Tanous         return;
21745ca1b86SEd Tanous     }
218adc4f0dbSShawn McCarney     const std::array<const char*, 2> interfaces = {
219734bfe90SGunnar Mills         "xyz.openbmc_project.Inventory.Item.Board",
220adc4f0dbSShawn McCarney         "xyz.openbmc_project.Inventory.Item.Chassis"};
221734bfe90SGunnar Mills 
22255c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
22362d5e2e4SEd Tanous         [asyncResp, chassisId(std::string(chassisId))](
22462d5e2e4SEd Tanous             const boost::system::error_code ec,
225b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
22662d5e2e4SEd Tanous         if (ec)
2271abe55efSEd Tanous         {
228f12894f8SJason M. Bills             messages::internalError(asyncResp->res);
229daf36e2eSEd Tanous             return;
230daf36e2eSEd Tanous         }
231daf36e2eSEd Tanous         // Iterate over all retrieved ObjectPaths.
232cf7eba09SNan Zhou         for (const std::pair<
233cf7eba09SNan Zhou                  std::string,
234cf7eba09SNan Zhou                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
2351214b7e7SGunnar Mills                  object : subtree)
2361abe55efSEd Tanous         {
237daf36e2eSEd Tanous             const std::string& path = object.first;
238cf7eba09SNan Zhou             const std::vector<std::pair<std::string, std::vector<std::string>>>&
2391214b7e7SGunnar Mills                 connectionNames = object.second;
2407e860f15SJohn Edward Broadbent 
241997093ebSGeorge Liu             sdbusplus::message::object_path objPath(path);
242997093ebSGeorge Liu             if (objPath.filename() != chassisId)
2431abe55efSEd Tanous             {
244daf36e2eSEd Tanous                 continue;
245daf36e2eSEd Tanous             }
24626f03899SShawn McCarney 
247002d39b4SEd Tanous             auto health = std::make_shared<HealthPopulate>(asyncResp);
248b49ac873SJames Feist 
2491e1e598dSJonathan Doman             sdbusplus::asio::getProperty<std::vector<std::string>>(
2501e1e598dSJonathan Doman                 *crow::connections::systemBus,
251002d39b4SEd Tanous                 "xyz.openbmc_project.ObjectMapper", path + "/all_sensors",
2521e1e598dSJonathan Doman                 "xyz.openbmc_project.Association", "endpoints",
253168e20c1SEd Tanous                 [health](const boost::system::error_code ec2,
2541e1e598dSJonathan Doman                          const std::vector<std::string>& resp) {
25523a21a1cSEd Tanous                 if (ec2)
256b49ac873SJames Feist                 {
257b49ac873SJames Feist                     return; // no sensors = no failures
258b49ac873SJames Feist                 }
2591e1e598dSJonathan Doman                 health->inventory = resp;
2601e1e598dSJonathan Doman                 });
261b49ac873SJames Feist 
262b49ac873SJames Feist             health->populate();
263b49ac873SJames Feist 
26426f6976fSEd Tanous             if (connectionNames.empty())
2651abe55efSEd Tanous             {
2661c8fba97SJames Feist                 BMCWEB_LOG_ERROR << "Got 0 Connection names";
267e0d918bcSEd Tanous                 continue;
268daf36e2eSEd Tanous             }
269e0d918bcSEd Tanous 
27049c53ac9SJohnathan Mantey             asyncResp->res.jsonValue["@odata.type"] =
2715ac5a2f4SGunnar Mills                 "#Chassis.v1_16_0.Chassis";
27249c53ac9SJohnathan Mantey             asyncResp->res.jsonValue["@odata.id"] =
27349c53ac9SJohnathan Mantey                 "/redfish/v1/Chassis/" + chassisId;
27449c53ac9SJohnathan Mantey             asyncResp->res.jsonValue["Name"] = "Chassis Collection";
27549c53ac9SJohnathan Mantey             asyncResp->res.jsonValue["ChassisType"] = "RackMount";
276cf7eba09SNan Zhou             asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]["target"] =
277cf7eba09SNan Zhou                 "/redfish/v1/Chassis/" + chassisId + "/Actions/Chassis.Reset";
2781476687dSEd Tanous             asyncResp->res
279cf7eba09SNan Zhou                 .jsonValue["Actions"]["#Chassis.Reset"]["@Redfish.ActionInfo"] =
280002d39b4SEd Tanous                 "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
2811476687dSEd Tanous             asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] =
2821476687dSEd Tanous                 "/redfish/v1/Systems/system/PCIeDevices";
28349c53ac9SJohnathan Mantey 
28492903bd4SJohn Edward Broadbent             sdbusplus::asio::getProperty<std::vector<std::string>>(
28592903bd4SJohn Edward Broadbent                 *crow::connections::systemBus,
28692903bd4SJohn Edward Broadbent                 "xyz.openbmc_project.ObjectMapper", path + "/drive",
28792903bd4SJohn Edward Broadbent                 "xyz.openbmc_project.Association", "endpoints",
288cf7eba09SNan Zhou                 [asyncResp, chassisId](const boost::system::error_code ec3,
28992903bd4SJohn Edward Broadbent                                        const std::vector<std::string>& resp) {
29092903bd4SJohn Edward Broadbent                 if (ec3 || resp.empty())
29192903bd4SJohn Edward Broadbent                 {
29292903bd4SJohn Edward Broadbent                     return; // no drives = no failures
29392903bd4SJohn Edward Broadbent                 }
29492903bd4SJohn Edward Broadbent 
29592903bd4SJohn Edward Broadbent                 nlohmann::json reference;
296a0cb40cbSJohn Edward Broadbent                 reference["@odata.id"] = crow::utility::urlFromPieces(
29792903bd4SJohn Edward Broadbent                     "redfish", "v1", "Chassis", chassisId, "Drives");
29892903bd4SJohn Edward Broadbent                 asyncResp->res.jsonValue["Drives"] = std::move(reference);
29992903bd4SJohn Edward Broadbent                 });
30092903bd4SJohn Edward Broadbent 
301002d39b4SEd Tanous             const std::string& connectionName = connectionNames[0].first;
3021c8fba97SJames Feist 
30323a21a1cSEd Tanous             const std::vector<std::string>& interfaces2 =
3041c8fba97SJames Feist                 connectionNames[0].second;
3051c8fba97SJames Feist             const std::array<const char*, 2> hasIndicatorLed = {
3061c8fba97SJames Feist                 "xyz.openbmc_project.Inventory.Item.Panel",
3070fda0f12SGeorge Liu                 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
3081c8fba97SJames Feist 
309476b9cc5STejas Patil             const std::string assetTagInterface =
3100fda0f12SGeorge Liu                 "xyz.openbmc_project.Inventory.Decorator.AssetTag";
311476b9cc5STejas Patil             if (std::find(interfaces2.begin(), interfaces2.end(),
312476b9cc5STejas Patil                           assetTagInterface) != interfaces2.end())
313476b9cc5STejas Patil             {
3141e1e598dSJonathan Doman                 sdbusplus::asio::getProperty<std::string>(
315002d39b4SEd Tanous                     *crow::connections::systemBus, connectionName, path,
316002d39b4SEd Tanous                     assetTagInterface, "AssetTag",
317476b9cc5STejas Patil                     [asyncResp, chassisId(std::string(chassisId))](
3188a592810SEd Tanous                         const boost::system::error_code ec2,
3191e1e598dSJonathan Doman                         const std::string& property) {
3208a592810SEd Tanous                     if (ec2)
321476b9cc5STejas Patil                     {
322cf7eba09SNan Zhou                         BMCWEB_LOG_DEBUG << "DBus response error for AssetTag";
323476b9cc5STejas Patil                         messages::internalError(asyncResp->res);
324476b9cc5STejas Patil                         return;
325476b9cc5STejas Patil                     }
326002d39b4SEd Tanous                     asyncResp->res.jsonValue["AssetTag"] = property;
3271e1e598dSJonathan Doman                     });
328476b9cc5STejas Patil             }
329476b9cc5STejas Patil 
3301c8fba97SJames Feist             for (const char* interface : hasIndicatorLed)
3311c8fba97SJames Feist             {
332002d39b4SEd Tanous                 if (std::find(interfaces2.begin(), interfaces2.end(),
33323a21a1cSEd Tanous                               interface) != interfaces2.end())
3341c8fba97SJames Feist                 {
3351c8fba97SJames Feist                     getIndicatorLedState(asyncResp);
3369f8bfa7cSGunnar Mills                     getLocationIndicatorActive(asyncResp);
3371c8fba97SJames Feist                     break;
3381c8fba97SJames Feist                 }
3391c8fba97SJames Feist             }
3401c8fba97SJames Feist 
341*86d89ed7SKrzysztof Grobelny             sdbusplus::asio::getAllProperties(
342*86d89ed7SKrzysztof Grobelny                 *crow::connections::systemBus, connectionName, path,
343*86d89ed7SKrzysztof Grobelny                 "xyz.openbmc_project.Inventory.Decorator.Asset",
34462d5e2e4SEd Tanous                 [asyncResp, chassisId(std::string(chassisId))](
34590728b54SEd Tanous                     const boost::system::error_code /*ec2*/,
346cf7eba09SNan Zhou                     const dbus::utility::DBusPropertiesMap& propertiesList) {
347*86d89ed7SKrzysztof Grobelny                 const std::string* partNumber = nullptr;
348*86d89ed7SKrzysztof Grobelny                 const std::string* serialNumber = nullptr;
349*86d89ed7SKrzysztof Grobelny                 const std::string* manufacturer = nullptr;
350*86d89ed7SKrzysztof Grobelny                 const std::string* model = nullptr;
351*86d89ed7SKrzysztof Grobelny                 const std::string* sparePartNumber = nullptr;
352*86d89ed7SKrzysztof Grobelny 
353*86d89ed7SKrzysztof Grobelny                 const bool success = sdbusplus::unpackPropertiesNoThrow(
354*86d89ed7SKrzysztof Grobelny                     dbus_utils::UnpackErrorPrinter(), propertiesList,
355*86d89ed7SKrzysztof Grobelny                     "PartNumber", partNumber, "SerialNumber", serialNumber,
356*86d89ed7SKrzysztof Grobelny                     "Manufacturer", manufacturer, "Model", model,
357*86d89ed7SKrzysztof Grobelny                     "SparePartNumber", sparePartNumber);
358*86d89ed7SKrzysztof Grobelny 
359*86d89ed7SKrzysztof Grobelny                 if (!success)
3601abe55efSEd Tanous                 {
361002d39b4SEd Tanous                     messages::internalError(asyncResp->res);
362caa11f7aSAlpana Kumari                     return;
363daf36e2eSEd Tanous                 }
364*86d89ed7SKrzysztof Grobelny 
365*86d89ed7SKrzysztof Grobelny                 if (partNumber != nullptr)
366*86d89ed7SKrzysztof Grobelny                 {
367*86d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["PartNumber"] = *partNumber;
368*86d89ed7SKrzysztof Grobelny                 }
369*86d89ed7SKrzysztof Grobelny 
370*86d89ed7SKrzysztof Grobelny                 if (serialNumber != nullptr)
371*86d89ed7SKrzysztof Grobelny                 {
372*86d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
373*86d89ed7SKrzysztof Grobelny                 }
374*86d89ed7SKrzysztof Grobelny 
375*86d89ed7SKrzysztof Grobelny                 if (manufacturer != nullptr)
376*86d89ed7SKrzysztof Grobelny                 {
377*86d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
378*86d89ed7SKrzysztof Grobelny                 }
379*86d89ed7SKrzysztof Grobelny 
380*86d89ed7SKrzysztof Grobelny                 if (model != nullptr)
381*86d89ed7SKrzysztof Grobelny                 {
382*86d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["Model"] = *model;
383*86d89ed7SKrzysztof Grobelny                 }
384*86d89ed7SKrzysztof Grobelny 
385caa11f7aSAlpana Kumari                 // SparePartNumber is optional on D-Bus
386caa11f7aSAlpana Kumari                 // so skip if it is empty
387*86d89ed7SKrzysztof Grobelny                 if (sparePartNumber != nullptr && !sparePartNumber->empty())
388caa11f7aSAlpana Kumari                 {
389*86d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["SparePartNumber"] =
390*86d89ed7SKrzysztof Grobelny                         *sparePartNumber;
391caa11f7aSAlpana Kumari                 }
392*86d89ed7SKrzysztof Grobelny 
39362d5e2e4SEd Tanous                 asyncResp->res.jsonValue["Name"] = chassisId;
39462d5e2e4SEd Tanous                 asyncResp->res.jsonValue["Id"] = chassisId;
3950256b694Szhanghch05 #ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL
396002d39b4SEd Tanous                 asyncResp->res.jsonValue["Thermal"]["@odata.id"] =
397002d39b4SEd Tanous                     "/redfish/v1/Chassis/" + chassisId + "/Thermal";
3982474adfaSEd Tanous                 // Power object
3991476687dSEd Tanous                 asyncResp->res.jsonValue["Power"]["@odata.id"] =
400002d39b4SEd Tanous                     "/redfish/v1/Chassis/" + chassisId + "/Power";
4010256b694Szhanghch05 #endif
4022973963eSXiaochao Ma #ifdef BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM
4032973963eSXiaochao Ma                 asyncResp->res.jsonValue["ThermalSubsystem"]["@odata.id"] =
4042973963eSXiaochao Ma                     crow::utility::urlFromPieces("redfish", "v1", "Chassis",
4052973963eSXiaochao Ma                                                  chassisId, "ThermalSubsystem");
4062973963eSXiaochao Ma #endif
40795a3ecadSAnthony Wilson                 // SensorCollection
408002d39b4SEd Tanous                 asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
409002d39b4SEd Tanous                     "/redfish/v1/Chassis/" + chassisId + "/Sensors";
410002d39b4SEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
4111476687dSEd Tanous 
4121476687dSEd Tanous                 nlohmann::json::array_t computerSystems;
4131476687dSEd Tanous                 nlohmann::json::object_t system;
414002d39b4SEd Tanous                 system["@odata.id"] = "/redfish/v1/Systems/system";
4151476687dSEd Tanous                 computerSystems.push_back(std::move(system));
416002d39b4SEd Tanous                 asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
4171476687dSEd Tanous                     std::move(computerSystems);
4181476687dSEd Tanous 
4191476687dSEd Tanous                 nlohmann::json::array_t managedBy;
4201476687dSEd Tanous                 nlohmann::json::object_t manager;
421002d39b4SEd Tanous                 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
4221476687dSEd Tanous                 managedBy.push_back(std::move(manager));
4237e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["Links"]["ManagedBy"] =
4241476687dSEd Tanous                     std::move(managedBy);
425beeca0aeSGunnar Mills                 getChassisState(asyncResp);
426*86d89ed7SKrzysztof Grobelny                 });
4272c37b4b0SSharad Yadav 
428308f70c7SWilly Tu             for (const auto& interface : interfaces2)
4292c37b4b0SSharad Yadav             {
430308f70c7SWilly Tu                 if (interface == "xyz.openbmc_project.Common.UUID")
4312c37b4b0SSharad Yadav                 {
432308f70c7SWilly Tu                     getChassisUUID(asyncResp, connectionName, path);
4332c37b4b0SSharad Yadav                 }
434cf7eba09SNan Zhou                 else if (interface ==
4350fda0f12SGeorge Liu                          "xyz.openbmc_project.Inventory.Decorator.LocationCode")
4362c37b4b0SSharad Yadav                 {
437002d39b4SEd Tanous                     getChassisLocationCode(asyncResp, connectionName, path);
4382c37b4b0SSharad Yadav                 }
4392c37b4b0SSharad Yadav             }
4402c37b4b0SSharad Yadav 
441daf36e2eSEd Tanous             return;
442daf36e2eSEd Tanous         }
443e0d918bcSEd Tanous 
444daf36e2eSEd Tanous         // Couldn't find an object with that name.  return an error
445cf7eba09SNan Zhou         messages::resourceNotFound(asyncResp->res, "#Chassis.v1_16_0.Chassis",
446cf7eba09SNan Zhou                                    chassisId);
447daf36e2eSEd Tanous         },
448daf36e2eSEd Tanous         "xyz.openbmc_project.ObjectMapper",
449daf36e2eSEd Tanous         "/xyz/openbmc_project/object_mapper",
450daf36e2eSEd Tanous         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
451271584abSEd Tanous         "/xyz/openbmc_project/inventory", 0, interfaces);
452c181942fSQiang XU 
453c181942fSQiang XU     getPhysicalSecurityData(asyncResp);
454cf7eba09SNan Zhou }
4551c8fba97SJames Feist 
456cf7eba09SNan Zhou inline void
457cf7eba09SNan Zhou     handleChassisPatch(App& app, const crow::Request& req,
4587e860f15SJohn Edward Broadbent                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
459cf7eba09SNan Zhou                        const std::string& param)
460cf7eba09SNan Zhou {
4613ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
46245ca1b86SEd Tanous     {
46345ca1b86SEd Tanous         return;
46445ca1b86SEd Tanous     }
4659f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
4661c8fba97SJames Feist     std::optional<std::string> indicatorLed;
4671c8fba97SJames Feist 
4687e860f15SJohn Edward Broadbent     if (param.empty())
4691c8fba97SJames Feist     {
4701c8fba97SJames Feist         return;
4711c8fba97SJames Feist     }
4721c8fba97SJames Feist 
47315ed6780SWilly Tu     if (!json_util::readJsonPatch(
4747e860f15SJohn Edward Broadbent             req, asyncResp->res, "LocationIndicatorActive",
4757e860f15SJohn Edward Broadbent             locationIndicatorActive, "IndicatorLED", indicatorLed))
4761c8fba97SJames Feist     {
4771c8fba97SJames Feist         return;
4781c8fba97SJames Feist     }
4791c8fba97SJames Feist 
4809f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
4819f8bfa7cSGunnar Mills     if (!locationIndicatorActive && !indicatorLed)
4821c8fba97SJames Feist     {
4831c8fba97SJames Feist         return; // delete this when we support more patch properties
4841c8fba97SJames Feist     }
485d6aa0093SGunnar Mills     if (indicatorLed)
486d6aa0093SGunnar Mills     {
4877e860f15SJohn Edward Broadbent         asyncResp->res.addHeader(
4887e860f15SJohn Edward Broadbent             boost::beast::http::field::warning,
4890fda0f12SGeorge Liu             "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
490d6aa0093SGunnar Mills     }
4911c8fba97SJames Feist 
4921c8fba97SJames Feist     const std::array<const char*, 2> interfaces = {
4931c8fba97SJames Feist         "xyz.openbmc_project.Inventory.Item.Board",
4941c8fba97SJames Feist         "xyz.openbmc_project.Inventory.Item.Chassis"};
4951c8fba97SJames Feist 
4967e860f15SJohn Edward Broadbent     const std::string& chassisId = param;
4971c8fba97SJames Feist 
4981c8fba97SJames Feist     crow::connections::systemBus->async_method_call(
499cf7eba09SNan Zhou         [asyncResp, chassisId, locationIndicatorActive,
500cf7eba09SNan Zhou          indicatorLed](const boost::system::error_code ec,
501b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
5021c8fba97SJames Feist         if (ec)
5031c8fba97SJames Feist         {
5041c8fba97SJames Feist             messages::internalError(asyncResp->res);
5051c8fba97SJames Feist             return;
5061c8fba97SJames Feist         }
5071c8fba97SJames Feist 
5081c8fba97SJames Feist         // Iterate over all retrieved ObjectPaths.
509cf7eba09SNan Zhou         for (const std::pair<
510cf7eba09SNan Zhou                  std::string,
511cf7eba09SNan Zhou                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
5121214b7e7SGunnar Mills                  object : subtree)
5131c8fba97SJames Feist         {
5141c8fba97SJames Feist             const std::string& path = object.first;
515cf7eba09SNan Zhou             const std::vector<std::pair<std::string, std::vector<std::string>>>&
5161214b7e7SGunnar Mills                 connectionNames = object.second;
5171c8fba97SJames Feist 
518997093ebSGeorge Liu             sdbusplus::message::object_path objPath(path);
519997093ebSGeorge Liu             if (objPath.filename() != chassisId)
5201c8fba97SJames Feist             {
5211c8fba97SJames Feist                 continue;
5221c8fba97SJames Feist             }
5231c8fba97SJames Feist 
52426f6976fSEd Tanous             if (connectionNames.empty())
5251c8fba97SJames Feist             {
5261c8fba97SJames Feist                 BMCWEB_LOG_ERROR << "Got 0 Connection names";
5271c8fba97SJames Feist                 continue;
5281c8fba97SJames Feist             }
5291c8fba97SJames Feist 
53023a21a1cSEd Tanous             const std::vector<std::string>& interfaces3 =
5311c8fba97SJames Feist                 connectionNames[0].second;
5321c8fba97SJames Feist 
5331c8fba97SJames Feist             const std::array<const char*, 2> hasIndicatorLed = {
5341c8fba97SJames Feist                 "xyz.openbmc_project.Inventory.Item.Panel",
5350fda0f12SGeorge Liu                 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
5361c8fba97SJames Feist             bool indicatorChassis = false;
5371c8fba97SJames Feist             for (const char* interface : hasIndicatorLed)
5381c8fba97SJames Feist             {
539002d39b4SEd Tanous                 if (std::find(interfaces3.begin(), interfaces3.end(),
54023a21a1cSEd Tanous                               interface) != interfaces3.end())
5411c8fba97SJames Feist                 {
5421c8fba97SJames Feist                     indicatorChassis = true;
5431c8fba97SJames Feist                     break;
5441c8fba97SJames Feist                 }
5451c8fba97SJames Feist             }
5469f8bfa7cSGunnar Mills             if (locationIndicatorActive)
5479f8bfa7cSGunnar Mills             {
5489f8bfa7cSGunnar Mills                 if (indicatorChassis)
5499f8bfa7cSGunnar Mills                 {
550002d39b4SEd Tanous                     setLocationIndicatorActive(asyncResp,
551002d39b4SEd Tanous                                                *locationIndicatorActive);
5529f8bfa7cSGunnar Mills                 }
5539f8bfa7cSGunnar Mills                 else
5549f8bfa7cSGunnar Mills                 {
555002d39b4SEd Tanous                     messages::propertyUnknown(asyncResp->res,
556002d39b4SEd Tanous                                               "LocationIndicatorActive");
5579f8bfa7cSGunnar Mills                 }
5589f8bfa7cSGunnar Mills             }
5599f8bfa7cSGunnar Mills             if (indicatorLed)
5609f8bfa7cSGunnar Mills             {
5611c8fba97SJames Feist                 if (indicatorChassis)
5621c8fba97SJames Feist                 {
563f23b7296SEd Tanous                     setIndicatorLedState(asyncResp, *indicatorLed);
5641c8fba97SJames Feist                 }
5651c8fba97SJames Feist                 else
5661c8fba97SJames Feist                 {
567cf7eba09SNan Zhou                     messages::propertyUnknown(asyncResp->res, "IndicatorLED");
5681c8fba97SJames Feist                 }
5691c8fba97SJames Feist             }
5701c8fba97SJames Feist             return;
5711c8fba97SJames Feist         }
5721c8fba97SJames Feist 
573cf7eba09SNan Zhou         messages::resourceNotFound(asyncResp->res, "#Chassis.v1_14_0.Chassis",
574cf7eba09SNan Zhou                                    chassisId);
5751c8fba97SJames Feist         },
5761c8fba97SJames Feist         "xyz.openbmc_project.ObjectMapper",
5771c8fba97SJames Feist         "/xyz/openbmc_project/object_mapper",
5781c8fba97SJames Feist         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5791c8fba97SJames Feist         "/xyz/openbmc_project/inventory", 0, interfaces);
580cf7eba09SNan Zhou }
581cf7eba09SNan Zhou 
582cf7eba09SNan Zhou /**
583cf7eba09SNan Zhou  * Chassis override class for delivering Chassis Schema
584cf7eba09SNan Zhou  * Functions triggers appropriate requests on DBus
585cf7eba09SNan Zhou  */
586cf7eba09SNan Zhou inline void requestRoutesChassis(App& app)
587cf7eba09SNan Zhou {
588cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
589cf7eba09SNan Zhou         .privileges(redfish::privileges::getChassis)
590cf7eba09SNan Zhou         .methods(boost::beast::http::verb::get)(
591cf7eba09SNan Zhou             std::bind_front(handleChassisGet, std::ref(app)));
592cf7eba09SNan Zhou 
593cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
594cf7eba09SNan Zhou         .privileges(redfish::privileges::patchChassis)
595cf7eba09SNan Zhou         .methods(boost::beast::http::verb::patch)(
596cf7eba09SNan Zhou             std::bind_front(handleChassisPatch, std::ref(app)));
5971c8fba97SJames Feist }
598dd99e04bSP.K. Lee 
5998d1b46d7Szhanghch05 inline void
6008d1b46d7Szhanghch05     doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
601dd99e04bSP.K. Lee {
602c3b3c92aSVijay Khemka     const char* busName = "xyz.openbmc_project.ObjectMapper";
603c3b3c92aSVijay Khemka     const char* path = "/xyz/openbmc_project/object_mapper";
604c3b3c92aSVijay Khemka     const char* interface = "xyz.openbmc_project.ObjectMapper";
605c3b3c92aSVijay Khemka     const char* method = "GetSubTreePaths";
606c3b3c92aSVijay Khemka 
607c3b3c92aSVijay Khemka     const std::array<const char*, 1> interfaces = {
608c3b3c92aSVijay Khemka         "xyz.openbmc_project.State.Chassis"};
609c3b3c92aSVijay Khemka 
610c3b3c92aSVijay Khemka     // Use mapper to get subtree paths.
611c3b3c92aSVijay Khemka     crow::connections::systemBus->async_method_call(
612b9d36b47SEd Tanous         [asyncResp](
613b9d36b47SEd Tanous             const boost::system::error_code ec,
614b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreePathsResponse& chassisList) {
615c3b3c92aSVijay Khemka         if (ec)
616c3b3c92aSVijay Khemka         {
617c3b3c92aSVijay Khemka             BMCWEB_LOG_DEBUG << "[mapper] Bad D-Bus request error: " << ec;
618c3b3c92aSVijay Khemka             messages::internalError(asyncResp->res);
619c3b3c92aSVijay Khemka             return;
620c3b3c92aSVijay Khemka         }
621c3b3c92aSVijay Khemka 
622dd99e04bSP.K. Lee         const char* processName = "xyz.openbmc_project.State.Chassis";
623dd99e04bSP.K. Lee         const char* interfaceName = "xyz.openbmc_project.State.Chassis";
624dd99e04bSP.K. Lee         const char* destProperty = "RequestedPowerTransition";
625dd99e04bSP.K. Lee         const std::string propertyValue =
626dd99e04bSP.K. Lee             "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
627002d39b4SEd Tanous         std::string objectPath = "/xyz/openbmc_project/state/chassis_system0";
628c3b3c92aSVijay Khemka 
629c3b3c92aSVijay Khemka         /* Look for system reset chassis path */
630002d39b4SEd Tanous         if ((std::find(chassisList.begin(), chassisList.end(), objectPath)) ==
631002d39b4SEd Tanous             chassisList.end())
632c3b3c92aSVijay Khemka         {
633c3b3c92aSVijay Khemka             /* We prefer to reset the full chassis_system, but if it doesn't
634c3b3c92aSVijay Khemka              * exist on some platforms, fall back to a host-only power reset
635c3b3c92aSVijay Khemka              */
636c3b3c92aSVijay Khemka             objectPath = "/xyz/openbmc_project/state/chassis0";
637c3b3c92aSVijay Khemka         }
638dd99e04bSP.K. Lee 
639dd99e04bSP.K. Lee         crow::connections::systemBus->async_method_call(
6408a592810SEd Tanous             [asyncResp](const boost::system::error_code ec2) {
641dd99e04bSP.K. Lee             // Use "Set" method to set the property value.
6428a592810SEd Tanous             if (ec2)
643dd99e04bSP.K. Lee             {
6448a592810SEd Tanous                 BMCWEB_LOG_DEBUG << "[Set] Bad D-Bus request error: " << ec2;
645dd99e04bSP.K. Lee                 messages::internalError(asyncResp->res);
646dd99e04bSP.K. Lee                 return;
647dd99e04bSP.K. Lee             }
648dd99e04bSP.K. Lee 
649dd99e04bSP.K. Lee             messages::success(asyncResp->res);
650dd99e04bSP.K. Lee             },
651002d39b4SEd Tanous             processName, objectPath, "org.freedesktop.DBus.Properties", "Set",
652002d39b4SEd Tanous             interfaceName, destProperty,
653168e20c1SEd Tanous             dbus::utility::DbusVariantType{propertyValue});
654c3b3c92aSVijay Khemka         },
655c3b3c92aSVijay Khemka         busName, path, interface, method, "/", 0, interfaces);
656dd99e04bSP.K. Lee }
657dd99e04bSP.K. Lee 
658cf7eba09SNan Zhou inline void handleChassisResetActionInfoPost(
659cf7eba09SNan Zhou     App& app, const crow::Request& req,
6607e860f15SJohn Edward Broadbent     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
661cf7eba09SNan Zhou     const std::string& /*chassisId*/)
662cf7eba09SNan Zhou {
6633ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
66445ca1b86SEd Tanous     {
66545ca1b86SEd Tanous         return;
66645ca1b86SEd Tanous     }
667dd99e04bSP.K. Lee     BMCWEB_LOG_DEBUG << "Post Chassis Reset.";
668dd99e04bSP.K. Lee 
669dd99e04bSP.K. Lee     std::string resetType;
670dd99e04bSP.K. Lee 
671cf7eba09SNan Zhou     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
672dd99e04bSP.K. Lee     {
673dd99e04bSP.K. Lee         return;
674dd99e04bSP.K. Lee     }
675dd99e04bSP.K. Lee 
676dd99e04bSP.K. Lee     if (resetType != "PowerCycle")
677dd99e04bSP.K. Lee     {
678dd99e04bSP.K. Lee         BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
679dd99e04bSP.K. Lee                          << resetType;
680002d39b4SEd Tanous         messages::actionParameterNotSupported(asyncResp->res, resetType,
681002d39b4SEd Tanous                                               "ResetType");
682dd99e04bSP.K. Lee 
683dd99e04bSP.K. Lee         return;
684dd99e04bSP.K. Lee     }
685dd99e04bSP.K. Lee     doChassisPowerCycle(asyncResp);
686dd99e04bSP.K. Lee }
6871cb1a9e6SAppaRao Puli 
6881cb1a9e6SAppaRao Puli /**
689cf7eba09SNan Zhou  * ChassisResetAction class supports the POST method for the Reset
690cf7eba09SNan Zhou  * action.
691cf7eba09SNan Zhou  * Function handles POST method request.
692cf7eba09SNan Zhou  * Analyzes POST body before sending Reset request data to D-Bus.
6931cb1a9e6SAppaRao Puli  */
694cf7eba09SNan Zhou 
695cf7eba09SNan Zhou inline void requestRoutesChassisResetAction(App& app)
6961cb1a9e6SAppaRao Puli {
697cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/")
698cf7eba09SNan Zhou         .privileges(redfish::privileges::postChassis)
699cf7eba09SNan Zhou         .methods(boost::beast::http::verb::post)(
700cf7eba09SNan Zhou             std::bind_front(handleChassisResetActionInfoPost, std::ref(app)));
701cf7eba09SNan Zhou }
702cf7eba09SNan Zhou 
703cf7eba09SNan Zhou inline void handleChassisResetActionInfoGet(
704cf7eba09SNan Zhou     App& app, const crow::Request& req,
7057e860f15SJohn Edward Broadbent     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
706cf7eba09SNan Zhou     const std::string& chassisId)
707cf7eba09SNan Zhou {
7083ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
7091cb1a9e6SAppaRao Puli     {
71045ca1b86SEd Tanous         return;
71145ca1b86SEd Tanous     }
712cf7eba09SNan Zhou     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
7131476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
7141476687dSEd Tanous         "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
7151476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
7161476687dSEd Tanous 
7171476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
7185b9e95a1SNan Zhou     nlohmann::json::array_t parameters;
7195b9e95a1SNan Zhou     nlohmann::json::object_t parameter;
7205b9e95a1SNan Zhou     parameter["Name"] = "ResetType";
7215b9e95a1SNan Zhou     parameter["Required"] = true;
7225b9e95a1SNan Zhou     parameter["DataType"] = "String";
7231476687dSEd Tanous     nlohmann::json::array_t allowed;
7241476687dSEd Tanous     allowed.push_back("PowerCycle");
7255b9e95a1SNan Zhou     parameter["AllowableValues"] = std::move(allowed);
7265b9e95a1SNan Zhou     parameters.push_back(std::move(parameter));
7275b9e95a1SNan Zhou 
7281476687dSEd Tanous     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
729cf7eba09SNan Zhou }
730cf7eba09SNan Zhou 
731cf7eba09SNan Zhou /**
732cf7eba09SNan Zhou  * ChassisResetActionInfo derived class for delivering Chassis
733cf7eba09SNan Zhou  * ResetType AllowableValues using ResetInfo schema.
734cf7eba09SNan Zhou  */
735cf7eba09SNan Zhou inline void requestRoutesChassisResetActionInfo(App& app)
736cf7eba09SNan Zhou {
737cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/")
738cf7eba09SNan Zhou         .privileges(redfish::privileges::getActionInfo)
739cf7eba09SNan Zhou         .methods(boost::beast::http::verb::get)(
740cf7eba09SNan Zhou             std::bind_front(handleChassisResetActionInfoGet, std::ref(app)));
7411cb1a9e6SAppaRao Puli }
7421cb1a9e6SAppaRao Puli 
743e37f8451SRapkiewicz, Pawel } // namespace redfish
744