blob: e2461e91267d4e3c3a20f5eb057ef364251fa236 [file] [log] [blame]
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +01001/*
Ed Tanous6be832e2024-09-10 11:44:48 -07002Copyright (c) 2018 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010015*/
16#pragma once
17
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080018#include "app.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080019#include "dbus_utility.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070020#include "generated/enums/action_info.hpp"
21#include "generated/enums/chassis.hpp"
22#include "generated/enums/resource.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080023#include "led.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080024#include "query.hpp"
Chau Ly7164bc62023-10-15 14:55:30 +000025#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080026#include "registries/privilege_registry.hpp"
27#include "utils/collection.hpp"
28#include "utils/dbus_utils.hpp"
Nan Zhoucf7eba02022-07-21 23:53:20 +000029#include "utils/json_utils.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -070030
George Liue99073f2022-12-09 11:06:16 +080031#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070032#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070033#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040034#include <sdbusplus/message.hpp>
Krzysztof Grobelny86d89ed2022-08-29 14:49:20 +020035#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050036
George Liu7a1dbc42022-12-07 16:03:22 +080037#include <array>
Joseph-Jonathan Salzano2952f642024-11-19 12:00:06 -070038#include <memory>
Ed Tanous3544d2a2023-08-06 18:12:20 -070039#include <ranges>
George Liu7a1dbc42022-12-07 16:03:22 +080040#include <string_view>
41
Ed Tanous1abe55e2018-09-05 08:30:59 -070042namespace redfish
43{
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010044
Joseph-Jonathan Salzano2952f642024-11-19 12:00:06 -070045inline chassis::ChassisType
46 translateChassisTypeToRedfish(const std::string_view& chassisType)
47{
48 if (chassisType ==
49 "xyz.openbmc_project.Inventory.Item.Chassis.ChassisType.Blade")
50 {
51 return chassis::ChassisType::Blade;
52 }
53 if (chassisType ==
54 "xyz.openbmc_project.Inventory.Item.Chassis.ChassisType.Component")
55 {
56 return chassis::ChassisType::Component;
57 }
58 if (chassisType ==
59 "xyz.openbmc_project.Inventory.Item.Chassis.ChassisType.Enclosure")
60 {
61 return chassis::ChassisType::Enclosure;
62 }
63 if (chassisType ==
64 "xyz.openbmc_project.Inventory.Item.Chassis.ChassisType.Module")
65 {
66 return chassis::ChassisType::Module;
67 }
68 if (chassisType ==
69 "xyz.openbmc_project.Inventory.Item.Chassis.ChassisType.RackMount")
70 {
71 return chassis::ChassisType::RackMount;
72 }
73 if (chassisType ==
74 "xyz.openbmc_project.Inventory.Item.Chassis.ChassisType.StandAlone")
75 {
76 return chassis::ChassisType::StandAlone;
77 }
78 if (chassisType ==
79 "xyz.openbmc_project.Inventory.Item.Chassis.ChassisType.StorageEnclosure")
80 {
81 return chassis::ChassisType::StorageEnclosure;
82 }
83 if (chassisType ==
84 "xyz.openbmc_project.Inventory.Item.Chassis.ChassisType.Zone")
85 {
86 return chassis::ChassisType::Zone;
87 }
88 return chassis::ChassisType::Invalid;
89}
90
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010091/**
Willy Tu5e577bc2022-07-26 00:41:55 +000092 * @brief Retrieves resources over dbus to link to the chassis
93 *
94 * @param[in] asyncResp - Shared pointer for completing asynchronous
95 * calls
96 * @param[in] path - Chassis dbus path to look for the storage.
97 *
98 * Calls the Association endpoints on the path + "/storage" and add the link of
99 * json["Links"]["Storage@odata.count"] =
100 * {"@odata.id", "/redfish/v1/Storage/" + resourceId}
101 *
102 * @return None.
103 */
104inline void getStorageLink(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
105 const sdbusplus::message::object_path& path)
106{
107 sdbusplus::asio::getProperty<std::vector<std::string>>(
108 *crow::connections::systemBus, "xyz.openbmc_project.ObjectMapper",
109 (path / "storage").str, "xyz.openbmc_project.Association", "endpoints",
Willy Tud4b054c2023-06-12 15:18:45 -0700110 [asyncResp](const boost::system::error_code& ec,
Willy Tu5e577bc2022-07-26 00:41:55 +0000111 const std::vector<std::string>& storageList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400112 if (ec)
Willy Tu5e577bc2022-07-26 00:41:55 +0000113 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400114 BMCWEB_LOG_DEBUG("getStorageLink got DBUS response error");
115 return;
Willy Tu5e577bc2022-07-26 00:41:55 +0000116 }
117
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400118 nlohmann::json::array_t storages;
119 for (const std::string& storagePath : storageList)
120 {
121 std::string id =
122 sdbusplus::message::object_path(storagePath).filename();
123 if (id.empty())
124 {
125 continue;
126 }
127
128 nlohmann::json::object_t storage;
129 storage["@odata.id"] =
130 boost::urls::format("/redfish/v1/Systems/{}/Storage/{}",
131 BMCWEB_REDFISH_SYSTEM_URI_NAME, id);
132 storages.emplace_back(std::move(storage));
133 }
134 asyncResp->res.jsonValue["Links"]["Storage@odata.count"] =
135 storages.size();
136 asyncResp->res.jsonValue["Links"]["Storage"] = std::move(storages);
137 });
Willy Tu5e577bc2022-07-26 00:41:55 +0000138}
139
140/**
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600141 * @brief Retrieves chassis state properties over dbus
142 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700143 * @param[in] asyncResp - Shared pointer for completing asynchronous calls.
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600144 *
145 * @return None.
146 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700147inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600148{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700149 // crow::connections::systemBus->async_method_call(
150 sdbusplus::asio::getProperty<std::string>(
151 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
152 "/xyz/openbmc_project/state/chassis0",
153 "xyz.openbmc_project.State.Chassis", "CurrentPowerState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700154 [asyncResp{std::move(asyncResp)}](const boost::system::error_code& ec,
155 const std::string& chassisState) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400156 if (ec)
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600157 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400158 if (ec == boost::system::errc::host_unreachable)
159 {
160 // Service not available, no error, just don't return
161 // chassis state info
162 BMCWEB_LOG_DEBUG("Service not available {}", ec);
163 return;
164 }
165 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
166 messages::internalError(asyncResp->res);
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600167 return;
168 }
169
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400170 BMCWEB_LOG_DEBUG("Chassis state: {}", chassisState);
171 // Verify Chassis State
172 if (chassisState ==
173 "xyz.openbmc_project.State.Chassis.PowerState.On")
174 {
175 asyncResp->res.jsonValue["PowerState"] =
176 resource::PowerState::On;
177 asyncResp->res.jsonValue["Status"]["State"] =
178 resource::State::Enabled;
179 }
180 else if (chassisState ==
181 "xyz.openbmc_project.State.Chassis.PowerState.Off")
182 {
183 asyncResp->res.jsonValue["PowerState"] =
184 resource::PowerState::Off;
185 asyncResp->res.jsonValue["Status"]["State"] =
186 resource::State::StandbyOffline;
187 }
188 });
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600189}
190
Qiang XUc1819422019-02-27 13:51:32 +0800191/**
192 * Retrieves physical security properties over dbus
193 */
Chau Ly7164bc62023-10-15 14:55:30 +0000194inline void handlePhysicalSecurityGetSubTree(
195 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
196 const boost::system::error_code& ec,
197 const dbus::utility::MapperGetSubTreeResponse& subtree)
Qiang XUc1819422019-02-27 13:51:32 +0800198{
Chau Ly7164bc62023-10-15 14:55:30 +0000199 if (ec)
200 {
201 // do not add err msg in redfish response, because this is not
202 // mandatory property
203 BMCWEB_LOG_INFO("DBUS error: no matched iface {}", ec);
204 return;
205 }
206 // Iterate over all retrieved ObjectPaths.
207 for (const auto& object : subtree)
208 {
209 if (!object.second.empty())
Ed Tanous002d39b2022-05-31 08:59:27 -0700210 {
Ed Tanous89144a32024-04-08 17:27:04 -0700211 const auto& service = object.second.front();
Chau Ly7164bc62023-10-15 14:55:30 +0000212
213 BMCWEB_LOG_DEBUG("Get intrusion status by service ");
214
215 sdbusplus::asio::getProperty<std::string>(
216 *crow::connections::systemBus, service.first, object.first,
217 "xyz.openbmc_project.Chassis.Intrusion", "Status",
218 [asyncResp](const boost::system::error_code& ec1,
219 const std::string& value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400220 if (ec1)
221 {
222 // do not add err msg in redfish response, because this
223 // is not
224 // mandatory property
225 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
226 return;
227 }
228 asyncResp->res.jsonValue["PhysicalSecurity"]
229 ["IntrusionSensorNumber"] = 1;
230 asyncResp->res
231 .jsonValue["PhysicalSecurity"]["IntrusionSensor"] =
232 value;
233 });
Chau Ly7164bc62023-10-15 14:55:30 +0000234
Ed Tanous002d39b2022-05-31 08:59:27 -0700235 return;
236 }
Chau Ly7164bc62023-10-15 14:55:30 +0000237 }
Qiang XUc1819422019-02-27 13:51:32 +0800238}
239
Nan Zhoucf7eba02022-07-21 23:53:20 +0000240inline void handleChassisCollectionGet(
241 App& app, const crow::Request& req,
242 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
243{
244 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
245 {
246 return;
247 }
248 asyncResp->res.jsonValue["@odata.type"] =
249 "#ChassisCollection.ChassisCollection";
250 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
251 asyncResp->res.jsonValue["Name"] = "Chassis Collection";
252
George Liu7a1dbc42022-12-07 16:03:22 +0800253 constexpr std::array<std::string_view, 2> interfaces{
254 "xyz.openbmc_project.Inventory.Item.Board",
255 "xyz.openbmc_project.Inventory.Item.Chassis"};
Nan Zhoucf7eba02022-07-21 23:53:20 +0000256 collection_util::getCollectionMembers(
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -0500257 asyncResp, boost::urls::url("/redfish/v1/Chassis"), interfaces,
258 "/xyz/openbmc_project/inventory");
Nan Zhoucf7eba02022-07-21 23:53:20 +0000259}
260
Jie Yanga5617492021-06-29 12:59:14 -0700261inline void getChassisContainedBy(
262 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
263 const std::string& chassisId, const boost::system::error_code& ec,
Myung Bae28ee5632024-05-24 13:10:04 -0500264 const dbus::utility::MapperGetSubTreePathsResponse& upstreamChassisPaths)
Jie Yanga5617492021-06-29 12:59:14 -0700265{
266 if (ec)
267 {
268 if (ec.value() != EBADR)
269 {
Ed Tanous62598e32023-07-17 17:06:25 -0700270 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Jie Yanga5617492021-06-29 12:59:14 -0700271 messages::internalError(asyncResp->res);
272 }
273 return;
274 }
275 if (upstreamChassisPaths.empty())
276 {
277 return;
278 }
279 if (upstreamChassisPaths.size() > 1)
280 {
Ed Tanous8ece0e42024-01-02 13:16:50 -0800281 BMCWEB_LOG_ERROR("{} is contained by multiple chassis", chassisId);
Jie Yanga5617492021-06-29 12:59:14 -0700282 messages::internalError(asyncResp->res);
283 return;
284 }
285
286 sdbusplus::message::object_path upstreamChassisPath(
287 upstreamChassisPaths[0]);
288 std::string upstreamChassis = upstreamChassisPath.filename();
289 if (upstreamChassis.empty())
290 {
Ed Tanous62598e32023-07-17 17:06:25 -0700291 BMCWEB_LOG_WARNING("Malformed upstream Chassis path {} on {}",
292 upstreamChassisPath.str, chassisId);
Jie Yanga5617492021-06-29 12:59:14 -0700293 return;
294 }
295
296 asyncResp->res.jsonValue["Links"]["ContainedBy"]["@odata.id"] =
297 boost::urls::format("/redfish/v1/Chassis/{}", upstreamChassis);
298}
299
300inline void getChassisContains(
301 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
302 const std::string& chassisId, const boost::system::error_code& ec,
Myung Bae28ee5632024-05-24 13:10:04 -0500303 const dbus::utility::MapperGetSubTreePathsResponse& downstreamChassisPaths)
Jie Yanga5617492021-06-29 12:59:14 -0700304{
305 if (ec)
306 {
307 if (ec.value() != EBADR)
308 {
Ed Tanous62598e32023-07-17 17:06:25 -0700309 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Jie Yanga5617492021-06-29 12:59:14 -0700310 messages::internalError(asyncResp->res);
311 }
312 return;
313 }
314 if (downstreamChassisPaths.empty())
315 {
316 return;
317 }
318 nlohmann::json& jValue = asyncResp->res.jsonValue["Links"]["Contains"];
319 if (!jValue.is_array())
320 {
321 // Create the array if it was empty
322 jValue = nlohmann::json::array();
323 }
324 for (const auto& p : downstreamChassisPaths)
325 {
326 sdbusplus::message::object_path downstreamChassisPath(p);
327 std::string downstreamChassis = downstreamChassisPath.filename();
328 if (downstreamChassis.empty())
329 {
Ed Tanous62598e32023-07-17 17:06:25 -0700330 BMCWEB_LOG_WARNING("Malformed downstream Chassis path {} on {}",
331 downstreamChassisPath.str, chassisId);
Jie Yanga5617492021-06-29 12:59:14 -0700332 continue;
333 }
334 nlohmann::json link;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400335 link["@odata.id"] =
336 boost::urls::format("/redfish/v1/Chassis/{}", downstreamChassis);
Jie Yanga5617492021-06-29 12:59:14 -0700337 jValue.push_back(std::move(link));
338 }
339 asyncResp->res.jsonValue["Links"]["Contains@odata.count"] = jValue.size();
340}
341
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400342inline void getChassisConnectivity(
343 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
344 const std::string& chassisId, const std::string& chassisPath)
Jie Yanga5617492021-06-29 12:59:14 -0700345{
Ed Tanous62598e32023-07-17 17:06:25 -0700346 BMCWEB_LOG_DEBUG("Get chassis connectivity");
Jie Yanga5617492021-06-29 12:59:14 -0700347
Myung Bae28ee5632024-05-24 13:10:04 -0500348 constexpr std::array<std::string_view, 2> interfaces{
349 "xyz.openbmc_project.Inventory.Item.Board",
350 "xyz.openbmc_project.Inventory.Item.Chassis"};
351
352 dbus::utility::getAssociatedSubTreePaths(
Jie Yanga5617492021-06-29 12:59:14 -0700353 chassisPath + "/contained_by",
Myung Bae28ee5632024-05-24 13:10:04 -0500354 sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
355 interfaces,
Jie Yanga5617492021-06-29 12:59:14 -0700356 std::bind_front(getChassisContainedBy, asyncResp, chassisId));
357
Myung Bae28ee5632024-05-24 13:10:04 -0500358 dbus::utility::getAssociatedSubTreePaths(
Jie Yanga5617492021-06-29 12:59:14 -0700359 chassisPath + "/containing",
Myung Bae28ee5632024-05-24 13:10:04 -0500360 sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
361 interfaces, std::bind_front(getChassisContains, asyncResp, chassisId));
Jie Yanga5617492021-06-29 12:59:14 -0700362}
363
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100364/**
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100365 * ChassisCollection derived class for delivering Chassis Collection Schema
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700366 * Functions triggers appropriate requests on DBus
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100367 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700368inline void requestRoutesChassisCollection(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700369{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700370 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/")
Ed Tanoused398212021-06-09 17:05:54 -0700371 .privileges(redfish::privileges::getChassisCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700372 .methods(boost::beast::http::verb::get)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000373 std::bind_front(handleChassisCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700374}
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100375
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400376inline void getChassisLocationCode(
377 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
378 const std::string& connectionName, const std::string& path)
Willy Tu308f70c2021-09-28 20:24:52 -0700379{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700380 sdbusplus::asio::getProperty<std::string>(
381 *crow::connections::systemBus, connectionName, path,
382 "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800383 [asyncResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700384 const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400385 if (ec)
386 {
387 BMCWEB_LOG_ERROR("DBUS response error for Location");
388 messages::internalError(asyncResp->res);
389 return;
390 }
Willy Tu308f70c2021-09-28 20:24:52 -0700391
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400392 asyncResp->res
393 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
394 property;
395 });
Willy Tu308f70c2021-09-28 20:24:52 -0700396}
397
398inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
399 const std::string& connectionName,
400 const std::string& path)
401{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700402 sdbusplus::asio::getProperty<std::string>(
403 *crow::connections::systemBus, connectionName, path,
404 "xyz.openbmc_project.Common.UUID", "UUID",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800405 [asyncResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700406 const std::string& chassisUUID) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400407 if (ec)
408 {
409 BMCWEB_LOG_ERROR("DBUS response error for UUID");
410 messages::internalError(asyncResp->res);
411 return;
412 }
413 asyncResp->res.jsonValue["UUID"] = chassisUUID;
414 });
Willy Tu308f70c2021-09-28 20:24:52 -0700415}
416
Chau Ly7164bc62023-10-15 14:55:30 +0000417inline void handleDecoratorAssetProperties(
418 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
419 const std::string& chassisId, const std::string& path,
420 const dbus::utility::DBusPropertiesMap& propertiesList)
421{
422 const std::string* partNumber = nullptr;
423 const std::string* serialNumber = nullptr;
424 const std::string* manufacturer = nullptr;
425 const std::string* model = nullptr;
426 const std::string* sparePartNumber = nullptr;
427
428 const bool success = sdbusplus::unpackPropertiesNoThrow(
429 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
430 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
431 "Model", model, "SparePartNumber", sparePartNumber);
432
433 if (!success)
434 {
435 messages::internalError(asyncResp->res);
436 return;
437 }
438
439 if (partNumber != nullptr)
440 {
441 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
442 }
443
444 if (serialNumber != nullptr)
445 {
446 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
447 }
448
449 if (manufacturer != nullptr)
450 {
451 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
452 }
453
454 if (model != nullptr)
455 {
456 asyncResp->res.jsonValue["Model"] = *model;
457 }
458
459 // SparePartNumber is optional on D-Bus
460 // so skip if it is empty
461 if (sparePartNumber != nullptr && !sparePartNumber->empty())
462 {
463 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
464 }
465
466 asyncResp->res.jsonValue["Name"] = chassisId;
467 asyncResp->res.jsonValue["Id"] = chassisId;
Ed Tanous25b54db2024-04-17 15:40:31 -0700468
469 if constexpr (BMCWEB_REDFISH_ALLOW_DEPRECATED_POWER_THERMAL)
470 {
471 asyncResp->res.jsonValue["Thermal"]["@odata.id"] =
472 boost::urls::format("/redfish/v1/Chassis/{}/Thermal", chassisId);
473 // Power object
474 asyncResp->res.jsonValue["Power"]["@odata.id"] =
475 boost::urls::format("/redfish/v1/Chassis/{}/Power", chassisId);
476 }
477
478 if constexpr (BMCWEB_REDFISH_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM)
479 {
480 asyncResp->res.jsonValue["ThermalSubsystem"]["@odata.id"] =
481 boost::urls::format("/redfish/v1/Chassis/{}/ThermalSubsystem",
482 chassisId);
483 asyncResp->res.jsonValue["PowerSubsystem"]["@odata.id"] =
484 boost::urls::format("/redfish/v1/Chassis/{}/PowerSubsystem",
485 chassisId);
486 asyncResp->res.jsonValue["EnvironmentMetrics"]["@odata.id"] =
487 boost::urls::format("/redfish/v1/Chassis/{}/EnvironmentMetrics",
488 chassisId);
489 }
Chau Ly7164bc62023-10-15 14:55:30 +0000490 // SensorCollection
491 asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
492 boost::urls::format("/redfish/v1/Chassis/{}/Sensors", chassisId);
Ed Tanous539d8c62024-06-19 14:38:27 -0700493 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
Chau Ly7164bc62023-10-15 14:55:30 +0000494
495 nlohmann::json::array_t computerSystems;
496 nlohmann::json::object_t system;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400497 system["@odata.id"] =
498 std::format("/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Chau Ly7164bc62023-10-15 14:55:30 +0000499 computerSystems.emplace_back(std::move(system));
500 asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
501 std::move(computerSystems);
502
503 nlohmann::json::array_t managedBy;
504 nlohmann::json::object_t manager;
Ed Tanous253f11b2024-05-16 09:38:31 -0700505 manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
506 BMCWEB_REDFISH_MANAGER_URI_NAME);
Chau Ly7164bc62023-10-15 14:55:30 +0000507 managedBy.emplace_back(std::move(manager));
508 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
509 getChassisState(asyncResp);
510 getStorageLink(asyncResp, path);
511}
512
Joseph-Jonathan Salzano2952f642024-11-19 12:00:06 -0700513inline void handleChassisProperties(
514 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
515 const dbus::utility::DBusPropertiesMap& propertiesList)
516{
517 const std::string* type = nullptr;
518
519 const bool success = sdbusplus::unpackPropertiesNoThrow(
520 dbus_utils::UnpackErrorPrinter(), propertiesList, "Type", type);
521
522 if (!success)
523 {
524 messages::internalError(asyncResp->res);
525 return;
526 }
527
Gunnar Mills19ea2862024-12-10 09:02:03 -0600528 // Chassis Type is a required property in Redfish
529 // If there is an error or some enum we don't support just sit it to Rack
530 // Mount
531 asyncResp->res.jsonValue["ChassisType"] = chassis::ChassisType::RackMount;
532
Joseph-Jonathan Salzano2952f642024-11-19 12:00:06 -0700533 if (type != nullptr)
534 {
535 auto chassisType = translateChassisTypeToRedfish(*type);
536 if (chassisType != chassis::ChassisType::Invalid)
537 {
538 asyncResp->res.jsonValue["ChassisType"] = chassisType;
539 }
540 }
Joseph-Jonathan Salzano2952f642024-11-19 12:00:06 -0700541}
542
Chau Ly7164bc62023-10-15 14:55:30 +0000543inline void handleChassisGetSubTree(
544 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
545 const std::string& chassisId, const boost::system::error_code& ec,
546 const dbus::utility::MapperGetSubTreeResponse& subtree)
547{
548 if (ec)
549 {
550 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
551 messages::internalError(asyncResp->res);
552 return;
553 }
554 // Iterate over all retrieved ObjectPaths.
555 for (const std::pair<
556 std::string,
557 std::vector<std::pair<std::string, std::vector<std::string>>>>&
558 object : subtree)
559 {
560 const std::string& path = object.first;
561 const std::vector<std::pair<std::string, std::vector<std::string>>>&
562 connectionNames = object.second;
563
564 sdbusplus::message::object_path objPath(path);
565 if (objPath.filename() != chassisId)
566 {
567 continue;
568 }
569
570 getChassisConnectivity(asyncResp, chassisId, path);
571
Chau Ly7164bc62023-10-15 14:55:30 +0000572 if (connectionNames.empty())
573 {
574 BMCWEB_LOG_ERROR("Got 0 Connection names");
575 continue;
576 }
577
578 asyncResp->res.jsonValue["@odata.type"] = "#Chassis.v1_22_0.Chassis";
579 asyncResp->res.jsonValue["@odata.id"] =
580 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
581 asyncResp->res.jsonValue["Name"] = "Chassis Collection";
Chau Ly7164bc62023-10-15 14:55:30 +0000582 asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]["target"] =
583 boost::urls::format("/redfish/v1/Chassis/{}/Actions/Chassis.Reset",
584 chassisId);
585 asyncResp->res
586 .jsonValue["Actions"]["#Chassis.Reset"]["@Redfish.ActionInfo"] =
587 boost::urls::format("/redfish/v1/Chassis/{}/ResetActionInfo",
588 chassisId);
Chau Ly7164bc62023-10-15 14:55:30 +0000589 dbus::utility::getAssociationEndPoints(
590 path + "/drive",
591 [asyncResp, chassisId](const boost::system::error_code& ec3,
592 const dbus::utility::MapperEndPoints& resp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400593 if (ec3 || resp.empty())
594 {
595 return; // no drives = no failures
596 }
Chau Ly7164bc62023-10-15 14:55:30 +0000597
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400598 nlohmann::json reference;
599 reference["@odata.id"] = boost::urls::format(
600 "/redfish/v1/Chassis/{}/Drives", chassisId);
601 asyncResp->res.jsonValue["Drives"] = std::move(reference);
602 });
Chau Ly7164bc62023-10-15 14:55:30 +0000603
604 const std::string& connectionName = connectionNames[0].first;
605
606 const std::vector<std::string>& interfaces2 = connectionNames[0].second;
George Liue5ae9c12021-11-16 10:31:23 +0800607 const std::array<const char*, 3> hasIndicatorLed = {
608 "xyz.openbmc_project.Inventory.Item.Chassis",
Chau Ly7164bc62023-10-15 14:55:30 +0000609 "xyz.openbmc_project.Inventory.Item.Panel",
610 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
611
612 const std::string assetTagInterface =
613 "xyz.openbmc_project.Inventory.Decorator.AssetTag";
614 const std::string replaceableInterface =
615 "xyz.openbmc_project.Inventory.Decorator.Replaceable";
Carson Labradob4d593f2024-02-16 22:34:32 +0000616 const std::string revisionInterface =
617 "xyz.openbmc_project.Inventory.Decorator.Revision";
Chau Ly7164bc62023-10-15 14:55:30 +0000618 for (const auto& interface : interfaces2)
619 {
620 if (interface == assetTagInterface)
621 {
622 sdbusplus::asio::getProperty<std::string>(
623 *crow::connections::systemBus, connectionName, path,
624 assetTagInterface, "AssetTag",
625 [asyncResp, chassisId](const boost::system::error_code& ec2,
626 const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400627 if (ec2)
628 {
629 BMCWEB_LOG_ERROR(
630 "DBus response error for AssetTag: {}", ec2);
631 messages::internalError(asyncResp->res);
632 return;
633 }
634 asyncResp->res.jsonValue["AssetTag"] = property;
635 });
Chau Ly7164bc62023-10-15 14:55:30 +0000636 }
637 else if (interface == replaceableInterface)
638 {
639 sdbusplus::asio::getProperty<bool>(
640 *crow::connections::systemBus, connectionName, path,
641 replaceableInterface, "HotPluggable",
642 [asyncResp, chassisId](const boost::system::error_code& ec2,
643 const bool property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400644 if (ec2)
645 {
646 BMCWEB_LOG_ERROR(
647 "DBus response error for HotPluggable: {}",
648 ec2);
649 messages::internalError(asyncResp->res);
650 return;
651 }
652 asyncResp->res.jsonValue["HotPluggable"] = property;
653 });
Chau Ly7164bc62023-10-15 14:55:30 +0000654 }
Carson Labradob4d593f2024-02-16 22:34:32 +0000655 else if (interface == revisionInterface)
656 {
657 sdbusplus::asio::getProperty<std::string>(
658 *crow::connections::systemBus, connectionName, path,
659 revisionInterface, "Version",
660 [asyncResp, chassisId](const boost::system::error_code& ec2,
661 const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400662 if (ec2)
663 {
664 BMCWEB_LOG_ERROR(
665 "DBus response error for Version: {}", ec2);
666 messages::internalError(asyncResp->res);
667 return;
668 }
669 asyncResp->res.jsonValue["Version"] = property;
670 });
Carson Labradob4d593f2024-02-16 22:34:32 +0000671 }
Chau Ly7164bc62023-10-15 14:55:30 +0000672 }
673
674 for (const char* interface : hasIndicatorLed)
675 {
676 if (std::ranges::find(interfaces2, interface) != interfaces2.end())
677 {
678 getIndicatorLedState(asyncResp);
679 getSystemLocationIndicatorActive(asyncResp);
680 break;
681 }
682 }
683
684 sdbusplus::asio::getAllProperties(
685 *crow::connections::systemBus, connectionName, path,
686 "xyz.openbmc_project.Inventory.Decorator.Asset",
687 [asyncResp, chassisId,
688 path](const boost::system::error_code&,
689 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400690 handleDecoratorAssetProperties(asyncResp, chassisId, path,
691 propertiesList);
692 });
Chau Ly7164bc62023-10-15 14:55:30 +0000693
Joseph-Jonathan Salzano2952f642024-11-19 12:00:06 -0700694 sdbusplus::asio::getAllProperties(
695 *crow::connections::systemBus, connectionName, path,
696 "xyz.openbmc_project.Inventory.Item.Chassis",
697 [asyncResp](
698 const boost::system::error_code&,
699 const dbus::utility::DBusPropertiesMap& propertiesList) {
700 handleChassisProperties(asyncResp, propertiesList);
701 });
702
Chau Ly7164bc62023-10-15 14:55:30 +0000703 for (const auto& interface : interfaces2)
704 {
705 if (interface == "xyz.openbmc_project.Common.UUID")
706 {
707 getChassisUUID(asyncResp, connectionName, path);
708 }
709 else if (interface ==
710 "xyz.openbmc_project.Inventory.Decorator.LocationCode")
711 {
712 getChassisLocationCode(asyncResp, connectionName, path);
713 }
714 }
715
716 return;
717 }
718
719 // Couldn't find an object with that name. return an error
720 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
721}
722
Nan Zhoucf7eba02022-07-21 23:53:20 +0000723inline void
724 handleChassisGet(App& app, const crow::Request& req,
725 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
726 const std::string& chassisId)
727{
728 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
729 {
730 return;
731 }
George Liue99073f2022-12-09 11:06:16 +0800732 constexpr std::array<std::string_view, 2> interfaces = {
Nan Zhoucf7eba02022-07-21 23:53:20 +0000733 "xyz.openbmc_project.Inventory.Item.Board",
734 "xyz.openbmc_project.Inventory.Item.Chassis"};
735
George Liue99073f2022-12-09 11:06:16 +0800736 dbus::utility::getSubTree(
737 "/xyz/openbmc_project/inventory", 0, interfaces,
Chau Ly7164bc62023-10-15 14:55:30 +0000738 std::bind_front(handleChassisGetSubTree, asyncResp, chassisId));
Nan Zhoucf7eba02022-07-21 23:53:20 +0000739
Chau Ly7164bc62023-10-15 14:55:30 +0000740 constexpr std::array<std::string_view, 1> interfaces2 = {
741 "xyz.openbmc_project.Chassis.Intrusion"};
Nan Zhoucf7eba02022-07-21 23:53:20 +0000742
Chau Ly7164bc62023-10-15 14:55:30 +0000743 dbus::utility::getSubTree(
744 "/xyz/openbmc_project", 0, interfaces2,
745 std::bind_front(handlePhysicalSecurityGetSubTree, asyncResp));
Nan Zhoucf7eba02022-07-21 23:53:20 +0000746}
747
748inline void
749 handleChassisPatch(App& app, const crow::Request& req,
750 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
751 const std::string& param)
752{
753 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
754 {
755 return;
756 }
757 std::optional<bool> locationIndicatorActive;
758 std::optional<std::string> indicatorLed;
759
760 if (param.empty())
761 {
762 return;
763 }
764
Myung Baeafc474a2024-10-09 00:53:29 -0700765 if (!json_util::readJsonPatch( //
766 req, asyncResp->res, //
767 "IndicatorLED", indicatorLed, //
768 "LocationIndicatorActive", locationIndicatorActive //
769 ))
Nan Zhoucf7eba02022-07-21 23:53:20 +0000770 {
771 return;
772 }
773
774 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
775 if (!locationIndicatorActive && !indicatorLed)
776 {
777 return; // delete this when we support more patch properties
778 }
779 if (indicatorLed)
780 {
781 asyncResp->res.addHeader(
782 boost::beast::http::field::warning,
783 "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
784 }
785
George Liue99073f2022-12-09 11:06:16 +0800786 constexpr std::array<std::string_view, 2> interfaces = {
Nan Zhoucf7eba02022-07-21 23:53:20 +0000787 "xyz.openbmc_project.Inventory.Item.Board",
788 "xyz.openbmc_project.Inventory.Item.Chassis"};
789
790 const std::string& chassisId = param;
791
George Liue99073f2022-12-09 11:06:16 +0800792 dbus::utility::getSubTree(
793 "/xyz/openbmc_project/inventory", 0, interfaces,
Nan Zhoucf7eba02022-07-21 23:53:20 +0000794 [asyncResp, chassisId, locationIndicatorActive,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800795 indicatorLed](const boost::system::error_code& ec,
Nan Zhoucf7eba02022-07-21 23:53:20 +0000796 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400797 if (ec)
Nan Zhoucf7eba02022-07-21 23:53:20 +0000798 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400799 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
800 messages::internalError(asyncResp->res);
801 return;
Nan Zhoucf7eba02022-07-21 23:53:20 +0000802 }
803
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400804 // Iterate over all retrieved ObjectPaths.
805 for (const std::pair<std::string,
806 std::vector<std::pair<
807 std::string, std::vector<std::string>>>>&
808 object : subtree)
Nan Zhoucf7eba02022-07-21 23:53:20 +0000809 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400810 const std::string& path = object.first;
811 const std::vector<
812 std::pair<std::string, std::vector<std::string>>>&
813 connectionNames = object.second;
814
815 sdbusplus::message::object_path objPath(path);
816 if (objPath.filename() != chassisId)
817 {
818 continue;
819 }
820
821 if (connectionNames.empty())
822 {
823 BMCWEB_LOG_ERROR("Got 0 Connection names");
824 continue;
825 }
826
827 const std::vector<std::string>& interfaces3 =
828 connectionNames[0].second;
829
830 const std::array<const char*, 3> hasIndicatorLed = {
831 "xyz.openbmc_project.Inventory.Item.Chassis",
832 "xyz.openbmc_project.Inventory.Item.Panel",
833 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
834 bool indicatorChassis = false;
835 for (const char* interface : hasIndicatorLed)
836 {
837 if (std::ranges::find(interfaces3, interface) !=
838 interfaces3.end())
839 {
840 indicatorChassis = true;
841 break;
842 }
843 }
844 if (locationIndicatorActive)
845 {
846 if (indicatorChassis)
847 {
848 setSystemLocationIndicatorActive(
849 asyncResp, *locationIndicatorActive);
850 }
851 else
852 {
853 messages::propertyUnknown(asyncResp->res,
854 "LocationIndicatorActive");
855 }
856 }
857 if (indicatorLed)
858 {
859 if (indicatorChassis)
860 {
861 setIndicatorLedState(asyncResp, *indicatorLed);
862 }
863 else
864 {
865 messages::propertyUnknown(asyncResp->res,
866 "IndicatorLED");
867 }
868 }
869 return;
Nan Zhoucf7eba02022-07-21 23:53:20 +0000870 }
871
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400872 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
873 });
Nan Zhoucf7eba02022-07-21 23:53:20 +0000874}
875
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100876/**
877 * Chassis override class for delivering Chassis Schema
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700878 * Functions triggers appropriate requests on DBus
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100879 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700880inline void requestRoutesChassis(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700881{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700882 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700883 .privileges(redfish::privileges::getChassis)
Ed Tanous002d39b2022-05-31 08:59:27 -0700884 .methods(boost::beast::http::verb::get)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000885 std::bind_front(handleChassisGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700886
887 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700888 .privileges(redfish::privileges::patchChassis)
Ed Tanous002d39b2022-05-31 08:59:27 -0700889 .methods(boost::beast::http::verb::patch)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000890 std::bind_front(handleChassisPatch, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700891}
P.K. Leedd99e042020-06-17 19:43:16 +0800892
zhanghch058d1b46d2021-04-01 11:18:24 +0800893inline void
894 doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
P.K. Leedd99e042020-06-17 19:43:16 +0800895{
George Liu7a1dbc42022-12-07 16:03:22 +0800896 constexpr std::array<std::string_view, 1> interfaces = {
Vijay Khemkac3b3c922020-09-22 23:00:12 -0700897 "xyz.openbmc_project.State.Chassis"};
898
899 // Use mapper to get subtree paths.
George Liu7a1dbc42022-12-07 16:03:22 +0800900 dbus::utility::getSubTreePaths(
901 "/", 0, interfaces,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800902 [asyncResp](
George Liu7a1dbc42022-12-07 16:03:22 +0800903 const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800904 const dbus::utility::MapperGetSubTreePathsResponse& chassisList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400905 if (ec)
906 {
907 BMCWEB_LOG_ERROR("[mapper] Bad D-Bus request error: {}", ec);
908 messages::internalError(asyncResp->res);
909 return;
910 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700911
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400912 const char* processName = "xyz.openbmc_project.State.Chassis";
913 const char* interfaceName = "xyz.openbmc_project.State.Chassis";
914 const char* destProperty = "RequestedPowerTransition";
915 const std::string propertyValue =
916 "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
917 std::string objectPath =
918 "/xyz/openbmc_project/state/chassis_system0";
Ed Tanous002d39b2022-05-31 08:59:27 -0700919
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400920 /* Look for system reset chassis path */
921 if ((std::ranges::find(chassisList, objectPath)) ==
922 chassisList.end())
923 {
924 /* We prefer to reset the full chassis_system, but if it doesn't
925 * exist on some platforms, fall back to a host-only power reset
926 */
927 objectPath = "/xyz/openbmc_project/state/chassis0";
928 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700929
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400930 setDbusProperty(asyncResp, "ResetType", processName, objectPath,
931 interfaceName, destProperty, propertyValue);
932 });
P.K. Leedd99e042020-06-17 19:43:16 +0800933}
934
Nan Zhoucf7eba02022-07-21 23:53:20 +0000935inline void handleChassisResetActionInfoPost(
936 App& app, const crow::Request& req,
937 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
938 const std::string& /*chassisId*/)
939{
940 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
941 {
942 return;
943 }
Ed Tanous62598e32023-07-17 17:06:25 -0700944 BMCWEB_LOG_DEBUG("Post Chassis Reset.");
Nan Zhoucf7eba02022-07-21 23:53:20 +0000945
946 std::string resetType;
947
948 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
949 {
950 return;
951 }
952
953 if (resetType != "PowerCycle")
954 {
Ed Tanous62598e32023-07-17 17:06:25 -0700955 BMCWEB_LOG_DEBUG("Invalid property value for ResetType: {}", resetType);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000956 messages::actionParameterNotSupported(asyncResp->res, resetType,
957 "ResetType");
958
959 return;
960 }
961 doChassisPowerCycle(asyncResp);
962}
963
P.K. Leedd99e042020-06-17 19:43:16 +0800964/**
965 * ChassisResetAction class supports the POST method for the Reset
966 * action.
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700967 * Function handles POST method request.
968 * Analyzes POST body before sending Reset request data to D-Bus.
P.K. Leedd99e042020-06-17 19:43:16 +0800969 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700970
971inline void requestRoutesChassisResetAction(App& app)
P.K. Leedd99e042020-06-17 19:43:16 +0800972{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700973 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -0700974 .privileges(redfish::privileges::postChassis)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700975 .methods(boost::beast::http::verb::post)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000976 std::bind_front(handleChassisResetActionInfoPost, std::ref(app)));
977}
P.K. Leedd99e042020-06-17 19:43:16 +0800978
Nan Zhoucf7eba02022-07-21 23:53:20 +0000979inline void handleChassisResetActionInfoGet(
980 App& app, const crow::Request& req,
981 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
982 const std::string& chassisId)
983{
984 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
985 {
986 return;
987 }
988 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700989 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
990 "/redfish/v1/Chassis/{}/ResetActionInfo", chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000991 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
P.K. Leedd99e042020-06-17 19:43:16 +0800992
Nan Zhoucf7eba02022-07-21 23:53:20 +0000993 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
994 nlohmann::json::array_t parameters;
995 nlohmann::json::object_t parameter;
996 parameter["Name"] = "ResetType";
997 parameter["Required"] = true;
Ed Tanous539d8c62024-06-19 14:38:27 -0700998 parameter["DataType"] = action_info::ParameterTypes::String;
Nan Zhoucf7eba02022-07-21 23:53:20 +0000999 nlohmann::json::array_t allowed;
Patrick Williamsad539542023-05-12 10:10:08 -05001000 allowed.emplace_back("PowerCycle");
Nan Zhoucf7eba02022-07-21 23:53:20 +00001001 parameter["AllowableValues"] = std::move(allowed);
Patrick Williamsad539542023-05-12 10:10:08 -05001002 parameters.emplace_back(std::move(parameter));
P.K. Leedd99e042020-06-17 19:43:16 +08001003
Nan Zhoucf7eba02022-07-21 23:53:20 +00001004 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001005}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05301006
1007/**
1008 * ChassisResetActionInfo derived class for delivering Chassis
1009 * ResetType AllowableValues using ResetInfo schema.
1010 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001011inline void requestRoutesChassisResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05301012{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001013 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07001014 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001015 .methods(boost::beast::http::verb::get)(
Nan Zhoucf7eba02022-07-21 23:53:20 +00001016 std::bind_front(handleChassisResetActionInfoGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001017}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05301018
Ed Tanous1abe55e2018-09-05 08:30:59 -07001019} // namespace redfish