xref: /openbmc/bmcweb/features/redfish/lib/chassis.hpp (revision 77b364371531be5c61d84d5e83dfd72444434dd0)
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>
2786d89ed7SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
2802f6ff19SGunnar Mills #include <utils/collection.hpp>
2986d89ed7SKrzysztof 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 
34186d89ed7SKrzysztof Grobelny             sdbusplus::asio::getAllProperties(
34286d89ed7SKrzysztof Grobelny                 *crow::connections::systemBus, connectionName, path,
34386d89ed7SKrzysztof 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) {
34786d89ed7SKrzysztof Grobelny                 const std::string* partNumber = nullptr;
34886d89ed7SKrzysztof Grobelny                 const std::string* serialNumber = nullptr;
34986d89ed7SKrzysztof Grobelny                 const std::string* manufacturer = nullptr;
35086d89ed7SKrzysztof Grobelny                 const std::string* model = nullptr;
35186d89ed7SKrzysztof Grobelny                 const std::string* sparePartNumber = nullptr;
35286d89ed7SKrzysztof Grobelny 
35386d89ed7SKrzysztof Grobelny                 const bool success = sdbusplus::unpackPropertiesNoThrow(
35486d89ed7SKrzysztof Grobelny                     dbus_utils::UnpackErrorPrinter(), propertiesList,
35586d89ed7SKrzysztof Grobelny                     "PartNumber", partNumber, "SerialNumber", serialNumber,
35686d89ed7SKrzysztof Grobelny                     "Manufacturer", manufacturer, "Model", model,
35786d89ed7SKrzysztof Grobelny                     "SparePartNumber", sparePartNumber);
35886d89ed7SKrzysztof Grobelny 
35986d89ed7SKrzysztof Grobelny                 if (!success)
3601abe55efSEd Tanous                 {
361002d39b4SEd Tanous                     messages::internalError(asyncResp->res);
362caa11f7aSAlpana Kumari                     return;
363daf36e2eSEd Tanous                 }
36486d89ed7SKrzysztof Grobelny 
36586d89ed7SKrzysztof Grobelny                 if (partNumber != nullptr)
36686d89ed7SKrzysztof Grobelny                 {
36786d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["PartNumber"] = *partNumber;
36886d89ed7SKrzysztof Grobelny                 }
36986d89ed7SKrzysztof Grobelny 
37086d89ed7SKrzysztof Grobelny                 if (serialNumber != nullptr)
37186d89ed7SKrzysztof Grobelny                 {
37286d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
37386d89ed7SKrzysztof Grobelny                 }
37486d89ed7SKrzysztof Grobelny 
37586d89ed7SKrzysztof Grobelny                 if (manufacturer != nullptr)
37686d89ed7SKrzysztof Grobelny                 {
37786d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
37886d89ed7SKrzysztof Grobelny                 }
37986d89ed7SKrzysztof Grobelny 
38086d89ed7SKrzysztof Grobelny                 if (model != nullptr)
38186d89ed7SKrzysztof Grobelny                 {
38286d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["Model"] = *model;
38386d89ed7SKrzysztof Grobelny                 }
38486d89ed7SKrzysztof Grobelny 
385caa11f7aSAlpana Kumari                 // SparePartNumber is optional on D-Bus
386caa11f7aSAlpana Kumari                 // so skip if it is empty
38786d89ed7SKrzysztof Grobelny                 if (sparePartNumber != nullptr && !sparePartNumber->empty())
388caa11f7aSAlpana Kumari                 {
38986d89ed7SKrzysztof Grobelny                     asyncResp->res.jsonValue["SparePartNumber"] =
39086d89ed7SKrzysztof Grobelny                         *sparePartNumber;
391caa11f7aSAlpana Kumari                 }
39286d89ed7SKrzysztof 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");
406*77b36437SChicago Duan                 asyncResp->res.jsonValue["PowerSubsystem"]["@odata.id"] =
407*77b36437SChicago Duan                     crow::utility::urlFromPieces("redfish", "v1", "Chassis",
408*77b36437SChicago Duan                                                  chassisId, "PowerSubsystem");
4092973963eSXiaochao Ma #endif
41095a3ecadSAnthony Wilson                 // SensorCollection
411002d39b4SEd Tanous                 asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
412002d39b4SEd Tanous                     "/redfish/v1/Chassis/" + chassisId + "/Sensors";
413002d39b4SEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
4141476687dSEd Tanous 
4151476687dSEd Tanous                 nlohmann::json::array_t computerSystems;
4161476687dSEd Tanous                 nlohmann::json::object_t system;
417002d39b4SEd Tanous                 system["@odata.id"] = "/redfish/v1/Systems/system";
4181476687dSEd Tanous                 computerSystems.push_back(std::move(system));
419002d39b4SEd Tanous                 asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
4201476687dSEd Tanous                     std::move(computerSystems);
4211476687dSEd Tanous 
4221476687dSEd Tanous                 nlohmann::json::array_t managedBy;
4231476687dSEd Tanous                 nlohmann::json::object_t manager;
424002d39b4SEd Tanous                 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
4251476687dSEd Tanous                 managedBy.push_back(std::move(manager));
4267e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["Links"]["ManagedBy"] =
4271476687dSEd Tanous                     std::move(managedBy);
428beeca0aeSGunnar Mills                 getChassisState(asyncResp);
42986d89ed7SKrzysztof Grobelny                 });
4302c37b4b0SSharad Yadav 
431308f70c7SWilly Tu             for (const auto& interface : interfaces2)
4322c37b4b0SSharad Yadav             {
433308f70c7SWilly Tu                 if (interface == "xyz.openbmc_project.Common.UUID")
4342c37b4b0SSharad Yadav                 {
435308f70c7SWilly Tu                     getChassisUUID(asyncResp, connectionName, path);
4362c37b4b0SSharad Yadav                 }
437cf7eba09SNan Zhou                 else if (interface ==
4380fda0f12SGeorge Liu                          "xyz.openbmc_project.Inventory.Decorator.LocationCode")
4392c37b4b0SSharad Yadav                 {
440002d39b4SEd Tanous                     getChassisLocationCode(asyncResp, connectionName, path);
4412c37b4b0SSharad Yadav                 }
4422c37b4b0SSharad Yadav             }
4432c37b4b0SSharad Yadav 
444daf36e2eSEd Tanous             return;
445daf36e2eSEd Tanous         }
446e0d918bcSEd Tanous 
447daf36e2eSEd Tanous         // Couldn't find an object with that name.  return an error
448d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
449daf36e2eSEd Tanous         },
450daf36e2eSEd Tanous         "xyz.openbmc_project.ObjectMapper",
451daf36e2eSEd Tanous         "/xyz/openbmc_project/object_mapper",
452daf36e2eSEd Tanous         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
453271584abSEd Tanous         "/xyz/openbmc_project/inventory", 0, interfaces);
454c181942fSQiang XU 
455c181942fSQiang XU     getPhysicalSecurityData(asyncResp);
456cf7eba09SNan Zhou }
4571c8fba97SJames Feist 
458cf7eba09SNan Zhou inline void
459cf7eba09SNan Zhou     handleChassisPatch(App& app, const crow::Request& req,
4607e860f15SJohn Edward Broadbent                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
461cf7eba09SNan Zhou                        const std::string& param)
462cf7eba09SNan Zhou {
4633ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
46445ca1b86SEd Tanous     {
46545ca1b86SEd Tanous         return;
46645ca1b86SEd Tanous     }
4679f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
4681c8fba97SJames Feist     std::optional<std::string> indicatorLed;
4691c8fba97SJames Feist 
4707e860f15SJohn Edward Broadbent     if (param.empty())
4711c8fba97SJames Feist     {
4721c8fba97SJames Feist         return;
4731c8fba97SJames Feist     }
4741c8fba97SJames Feist 
47515ed6780SWilly Tu     if (!json_util::readJsonPatch(
4767e860f15SJohn Edward Broadbent             req, asyncResp->res, "LocationIndicatorActive",
4777e860f15SJohn Edward Broadbent             locationIndicatorActive, "IndicatorLED", indicatorLed))
4781c8fba97SJames Feist     {
4791c8fba97SJames Feist         return;
4801c8fba97SJames Feist     }
4811c8fba97SJames Feist 
4829f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
4839f8bfa7cSGunnar Mills     if (!locationIndicatorActive && !indicatorLed)
4841c8fba97SJames Feist     {
4851c8fba97SJames Feist         return; // delete this when we support more patch properties
4861c8fba97SJames Feist     }
487d6aa0093SGunnar Mills     if (indicatorLed)
488d6aa0093SGunnar Mills     {
4897e860f15SJohn Edward Broadbent         asyncResp->res.addHeader(
4907e860f15SJohn Edward Broadbent             boost::beast::http::field::warning,
4910fda0f12SGeorge Liu             "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
492d6aa0093SGunnar Mills     }
4931c8fba97SJames Feist 
4941c8fba97SJames Feist     const std::array<const char*, 2> interfaces = {
4951c8fba97SJames Feist         "xyz.openbmc_project.Inventory.Item.Board",
4961c8fba97SJames Feist         "xyz.openbmc_project.Inventory.Item.Chassis"};
4971c8fba97SJames Feist 
4987e860f15SJohn Edward Broadbent     const std::string& chassisId = param;
4991c8fba97SJames Feist 
5001c8fba97SJames Feist     crow::connections::systemBus->async_method_call(
501cf7eba09SNan Zhou         [asyncResp, chassisId, locationIndicatorActive,
502cf7eba09SNan Zhou          indicatorLed](const boost::system::error_code ec,
503b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
5041c8fba97SJames Feist         if (ec)
5051c8fba97SJames Feist         {
5061c8fba97SJames Feist             messages::internalError(asyncResp->res);
5071c8fba97SJames Feist             return;
5081c8fba97SJames Feist         }
5091c8fba97SJames Feist 
5101c8fba97SJames Feist         // Iterate over all retrieved ObjectPaths.
511cf7eba09SNan Zhou         for (const std::pair<
512cf7eba09SNan Zhou                  std::string,
513cf7eba09SNan Zhou                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
5141214b7e7SGunnar Mills                  object : subtree)
5151c8fba97SJames Feist         {
5161c8fba97SJames Feist             const std::string& path = object.first;
517cf7eba09SNan Zhou             const std::vector<std::pair<std::string, std::vector<std::string>>>&
5181214b7e7SGunnar Mills                 connectionNames = object.second;
5191c8fba97SJames Feist 
520997093ebSGeorge Liu             sdbusplus::message::object_path objPath(path);
521997093ebSGeorge Liu             if (objPath.filename() != chassisId)
5221c8fba97SJames Feist             {
5231c8fba97SJames Feist                 continue;
5241c8fba97SJames Feist             }
5251c8fba97SJames Feist 
52626f6976fSEd Tanous             if (connectionNames.empty())
5271c8fba97SJames Feist             {
5281c8fba97SJames Feist                 BMCWEB_LOG_ERROR << "Got 0 Connection names";
5291c8fba97SJames Feist                 continue;
5301c8fba97SJames Feist             }
5311c8fba97SJames Feist 
53223a21a1cSEd Tanous             const std::vector<std::string>& interfaces3 =
5331c8fba97SJames Feist                 connectionNames[0].second;
5341c8fba97SJames Feist 
5351c8fba97SJames Feist             const std::array<const char*, 2> hasIndicatorLed = {
5361c8fba97SJames Feist                 "xyz.openbmc_project.Inventory.Item.Panel",
5370fda0f12SGeorge Liu                 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
5381c8fba97SJames Feist             bool indicatorChassis = false;
5391c8fba97SJames Feist             for (const char* interface : hasIndicatorLed)
5401c8fba97SJames Feist             {
541002d39b4SEd Tanous                 if (std::find(interfaces3.begin(), interfaces3.end(),
54223a21a1cSEd Tanous                               interface) != interfaces3.end())
5431c8fba97SJames Feist                 {
5441c8fba97SJames Feist                     indicatorChassis = true;
5451c8fba97SJames Feist                     break;
5461c8fba97SJames Feist                 }
5471c8fba97SJames Feist             }
5489f8bfa7cSGunnar Mills             if (locationIndicatorActive)
5499f8bfa7cSGunnar Mills             {
5509f8bfa7cSGunnar Mills                 if (indicatorChassis)
5519f8bfa7cSGunnar Mills                 {
552002d39b4SEd Tanous                     setLocationIndicatorActive(asyncResp,
553002d39b4SEd Tanous                                                *locationIndicatorActive);
5549f8bfa7cSGunnar Mills                 }
5559f8bfa7cSGunnar Mills                 else
5569f8bfa7cSGunnar Mills                 {
557002d39b4SEd Tanous                     messages::propertyUnknown(asyncResp->res,
558002d39b4SEd Tanous                                               "LocationIndicatorActive");
5599f8bfa7cSGunnar Mills                 }
5609f8bfa7cSGunnar Mills             }
5619f8bfa7cSGunnar Mills             if (indicatorLed)
5629f8bfa7cSGunnar Mills             {
5631c8fba97SJames Feist                 if (indicatorChassis)
5641c8fba97SJames Feist                 {
565f23b7296SEd Tanous                     setIndicatorLedState(asyncResp, *indicatorLed);
5661c8fba97SJames Feist                 }
5671c8fba97SJames Feist                 else
5681c8fba97SJames Feist                 {
569cf7eba09SNan Zhou                     messages::propertyUnknown(asyncResp->res, "IndicatorLED");
5701c8fba97SJames Feist                 }
5711c8fba97SJames Feist             }
5721c8fba97SJames Feist             return;
5731c8fba97SJames Feist         }
5741c8fba97SJames Feist 
575d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
5761c8fba97SJames Feist         },
5771c8fba97SJames Feist         "xyz.openbmc_project.ObjectMapper",
5781c8fba97SJames Feist         "/xyz/openbmc_project/object_mapper",
5791c8fba97SJames Feist         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5801c8fba97SJames Feist         "/xyz/openbmc_project/inventory", 0, interfaces);
581cf7eba09SNan Zhou }
582cf7eba09SNan Zhou 
583cf7eba09SNan Zhou /**
584cf7eba09SNan Zhou  * Chassis override class for delivering Chassis Schema
585cf7eba09SNan Zhou  * Functions triggers appropriate requests on DBus
586cf7eba09SNan Zhou  */
587cf7eba09SNan Zhou inline void requestRoutesChassis(App& app)
588cf7eba09SNan Zhou {
589cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
590cf7eba09SNan Zhou         .privileges(redfish::privileges::getChassis)
591cf7eba09SNan Zhou         .methods(boost::beast::http::verb::get)(
592cf7eba09SNan Zhou             std::bind_front(handleChassisGet, std::ref(app)));
593cf7eba09SNan Zhou 
594cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
595cf7eba09SNan Zhou         .privileges(redfish::privileges::patchChassis)
596cf7eba09SNan Zhou         .methods(boost::beast::http::verb::patch)(
597cf7eba09SNan Zhou             std::bind_front(handleChassisPatch, std::ref(app)));
5981c8fba97SJames Feist }
599dd99e04bSP.K. Lee 
6008d1b46d7Szhanghch05 inline void
6018d1b46d7Szhanghch05     doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
602dd99e04bSP.K. Lee {
603c3b3c92aSVijay Khemka     const char* busName = "xyz.openbmc_project.ObjectMapper";
604c3b3c92aSVijay Khemka     const char* path = "/xyz/openbmc_project/object_mapper";
605c3b3c92aSVijay Khemka     const char* interface = "xyz.openbmc_project.ObjectMapper";
606c3b3c92aSVijay Khemka     const char* method = "GetSubTreePaths";
607c3b3c92aSVijay Khemka 
608c3b3c92aSVijay Khemka     const std::array<const char*, 1> interfaces = {
609c3b3c92aSVijay Khemka         "xyz.openbmc_project.State.Chassis"};
610c3b3c92aSVijay Khemka 
611c3b3c92aSVijay Khemka     // Use mapper to get subtree paths.
612c3b3c92aSVijay Khemka     crow::connections::systemBus->async_method_call(
613b9d36b47SEd Tanous         [asyncResp](
614b9d36b47SEd Tanous             const boost::system::error_code ec,
615b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreePathsResponse& chassisList) {
616c3b3c92aSVijay Khemka         if (ec)
617c3b3c92aSVijay Khemka         {
618c3b3c92aSVijay Khemka             BMCWEB_LOG_DEBUG << "[mapper] Bad D-Bus request error: " << ec;
619c3b3c92aSVijay Khemka             messages::internalError(asyncResp->res);
620c3b3c92aSVijay Khemka             return;
621c3b3c92aSVijay Khemka         }
622c3b3c92aSVijay Khemka 
623dd99e04bSP.K. Lee         const char* processName = "xyz.openbmc_project.State.Chassis";
624dd99e04bSP.K. Lee         const char* interfaceName = "xyz.openbmc_project.State.Chassis";
625dd99e04bSP.K. Lee         const char* destProperty = "RequestedPowerTransition";
626dd99e04bSP.K. Lee         const std::string propertyValue =
627dd99e04bSP.K. Lee             "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
628002d39b4SEd Tanous         std::string objectPath = "/xyz/openbmc_project/state/chassis_system0";
629c3b3c92aSVijay Khemka 
630c3b3c92aSVijay Khemka         /* Look for system reset chassis path */
631002d39b4SEd Tanous         if ((std::find(chassisList.begin(), chassisList.end(), objectPath)) ==
632002d39b4SEd Tanous             chassisList.end())
633c3b3c92aSVijay Khemka         {
634c3b3c92aSVijay Khemka             /* We prefer to reset the full chassis_system, but if it doesn't
635c3b3c92aSVijay Khemka              * exist on some platforms, fall back to a host-only power reset
636c3b3c92aSVijay Khemka              */
637c3b3c92aSVijay Khemka             objectPath = "/xyz/openbmc_project/state/chassis0";
638c3b3c92aSVijay Khemka         }
639dd99e04bSP.K. Lee 
640dd99e04bSP.K. Lee         crow::connections::systemBus->async_method_call(
6418a592810SEd Tanous             [asyncResp](const boost::system::error_code ec2) {
642dd99e04bSP.K. Lee             // Use "Set" method to set the property value.
6438a592810SEd Tanous             if (ec2)
644dd99e04bSP.K. Lee             {
6458a592810SEd Tanous                 BMCWEB_LOG_DEBUG << "[Set] Bad D-Bus request error: " << ec2;
646dd99e04bSP.K. Lee                 messages::internalError(asyncResp->res);
647dd99e04bSP.K. Lee                 return;
648dd99e04bSP.K. Lee             }
649dd99e04bSP.K. Lee 
650dd99e04bSP.K. Lee             messages::success(asyncResp->res);
651dd99e04bSP.K. Lee             },
652002d39b4SEd Tanous             processName, objectPath, "org.freedesktop.DBus.Properties", "Set",
653002d39b4SEd Tanous             interfaceName, destProperty,
654168e20c1SEd Tanous             dbus::utility::DbusVariantType{propertyValue});
655c3b3c92aSVijay Khemka         },
656c3b3c92aSVijay Khemka         busName, path, interface, method, "/", 0, interfaces);
657dd99e04bSP.K. Lee }
658dd99e04bSP.K. Lee 
659cf7eba09SNan Zhou inline void handleChassisResetActionInfoPost(
660cf7eba09SNan Zhou     App& app, const crow::Request& req,
6617e860f15SJohn Edward Broadbent     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
662cf7eba09SNan Zhou     const std::string& /*chassisId*/)
663cf7eba09SNan Zhou {
6643ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
66545ca1b86SEd Tanous     {
66645ca1b86SEd Tanous         return;
66745ca1b86SEd Tanous     }
668dd99e04bSP.K. Lee     BMCWEB_LOG_DEBUG << "Post Chassis Reset.";
669dd99e04bSP.K. Lee 
670dd99e04bSP.K. Lee     std::string resetType;
671dd99e04bSP.K. Lee 
672cf7eba09SNan Zhou     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
673dd99e04bSP.K. Lee     {
674dd99e04bSP.K. Lee         return;
675dd99e04bSP.K. Lee     }
676dd99e04bSP.K. Lee 
677dd99e04bSP.K. Lee     if (resetType != "PowerCycle")
678dd99e04bSP.K. Lee     {
679dd99e04bSP.K. Lee         BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
680dd99e04bSP.K. Lee                          << resetType;
681002d39b4SEd Tanous         messages::actionParameterNotSupported(asyncResp->res, resetType,
682002d39b4SEd Tanous                                               "ResetType");
683dd99e04bSP.K. Lee 
684dd99e04bSP.K. Lee         return;
685dd99e04bSP.K. Lee     }
686dd99e04bSP.K. Lee     doChassisPowerCycle(asyncResp);
687dd99e04bSP.K. Lee }
6881cb1a9e6SAppaRao Puli 
6891cb1a9e6SAppaRao Puli /**
690cf7eba09SNan Zhou  * ChassisResetAction class supports the POST method for the Reset
691cf7eba09SNan Zhou  * action.
692cf7eba09SNan Zhou  * Function handles POST method request.
693cf7eba09SNan Zhou  * Analyzes POST body before sending Reset request data to D-Bus.
6941cb1a9e6SAppaRao Puli  */
695cf7eba09SNan Zhou 
696cf7eba09SNan Zhou inline void requestRoutesChassisResetAction(App& app)
6971cb1a9e6SAppaRao Puli {
698cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/")
699cf7eba09SNan Zhou         .privileges(redfish::privileges::postChassis)
700cf7eba09SNan Zhou         .methods(boost::beast::http::verb::post)(
701cf7eba09SNan Zhou             std::bind_front(handleChassisResetActionInfoPost, std::ref(app)));
702cf7eba09SNan Zhou }
703cf7eba09SNan Zhou 
704cf7eba09SNan Zhou inline void handleChassisResetActionInfoGet(
705cf7eba09SNan Zhou     App& app, const crow::Request& req,
7067e860f15SJohn Edward Broadbent     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
707cf7eba09SNan Zhou     const std::string& chassisId)
708cf7eba09SNan Zhou {
7093ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
7101cb1a9e6SAppaRao Puli     {
71145ca1b86SEd Tanous         return;
71245ca1b86SEd Tanous     }
713cf7eba09SNan Zhou     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
7141476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
7151476687dSEd Tanous         "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
7161476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
7171476687dSEd Tanous 
7181476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
7195b9e95a1SNan Zhou     nlohmann::json::array_t parameters;
7205b9e95a1SNan Zhou     nlohmann::json::object_t parameter;
7215b9e95a1SNan Zhou     parameter["Name"] = "ResetType";
7225b9e95a1SNan Zhou     parameter["Required"] = true;
7235b9e95a1SNan Zhou     parameter["DataType"] = "String";
7241476687dSEd Tanous     nlohmann::json::array_t allowed;
7251476687dSEd Tanous     allowed.push_back("PowerCycle");
7265b9e95a1SNan Zhou     parameter["AllowableValues"] = std::move(allowed);
7275b9e95a1SNan Zhou     parameters.push_back(std::move(parameter));
7285b9e95a1SNan Zhou 
7291476687dSEd Tanous     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
730cf7eba09SNan Zhou }
731cf7eba09SNan Zhou 
732cf7eba09SNan Zhou /**
733cf7eba09SNan Zhou  * ChassisResetActionInfo derived class for delivering Chassis
734cf7eba09SNan Zhou  * ResetType AllowableValues using ResetInfo schema.
735cf7eba09SNan Zhou  */
736cf7eba09SNan Zhou inline void requestRoutesChassisResetActionInfo(App& app)
737cf7eba09SNan Zhou {
738cf7eba09SNan Zhou     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/")
739cf7eba09SNan Zhou         .privileges(redfish::privileges::getActionInfo)
740cf7eba09SNan Zhou         .methods(boost::beast::http::verb::get)(
741cf7eba09SNan Zhou             std::bind_front(handleChassisResetActionInfoGet, std::ref(app)));
7421cb1a9e6SAppaRao Puli }
7431cb1a9e6SAppaRao Puli 
744e37f8451SRapkiewicz, Pawel } // namespace redfish
745