blob: 397e31cc5b38c35c612d05e2cc61884fa31ffd4a [file] [log] [blame]
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +01001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080021#include "dbus_utility.hpp"
James Feistb49ac872019-05-21 15:12:01 -070022#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080023#include "led.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080024#include "query.hpp"
25#include "registries/privilege_registry.hpp"
26#include "utils/collection.hpp"
27#include "utils/dbus_utils.hpp"
Nan Zhoucf7eba02022-07-21 23:53:20 +000028#include "utils/json_utils.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -070029
George Liue99073f2022-12-09 11:06:16 +080030#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070031#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070032#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040033#include <sdbusplus/message.hpp>
Krzysztof Grobelny86d89ed2022-08-29 14:49:20 +020034#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050035
George Liu7a1dbc42022-12-07 16:03:22 +080036#include <array>
37#include <string_view>
38
Ed Tanous1abe55e2018-09-05 08:30:59 -070039namespace redfish
40{
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010041
42/**
Willy Tu5e577bc2022-07-26 00:41:55 +000043 * @brief Retrieves resources over dbus to link to the chassis
44 *
45 * @param[in] asyncResp - Shared pointer for completing asynchronous
46 * calls
47 * @param[in] path - Chassis dbus path to look for the storage.
48 *
49 * Calls the Association endpoints on the path + "/storage" and add the link of
50 * json["Links"]["Storage@odata.count"] =
51 * {"@odata.id", "/redfish/v1/Storage/" + resourceId}
52 *
53 * @return None.
54 */
55inline void getStorageLink(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
56 const sdbusplus::message::object_path& path)
57{
58 sdbusplus::asio::getProperty<std::vector<std::string>>(
59 *crow::connections::systemBus, "xyz.openbmc_project.ObjectMapper",
60 (path / "storage").str, "xyz.openbmc_project.Association", "endpoints",
Willy Tud4b054c2023-06-12 15:18:45 -070061 [asyncResp](const boost::system::error_code& ec,
Willy Tu5e577bc2022-07-26 00:41:55 +000062 const std::vector<std::string>& storageList) {
63 if (ec)
64 {
Ed Tanous62598e32023-07-17 17:06:25 -070065 BMCWEB_LOG_DEBUG("getStorageLink got DBUS response error");
Willy Tu5e577bc2022-07-26 00:41:55 +000066 return;
67 }
68
69 nlohmann::json::array_t storages;
70 for (const std::string& storagePath : storageList)
71 {
72 std::string id =
73 sdbusplus::message::object_path(storagePath).filename();
74 if (id.empty())
75 {
76 continue;
77 }
78
79 nlohmann::json::object_t storage;
80 storage["@odata.id"] = boost::urls::format(
81 "/redfish/v1/Systems/system/Storage/{}", id);
82 storages.emplace_back(std::move(storage));
83 }
84 asyncResp->res.jsonValue["Links"]["Storage@odata.count"] =
85 storages.size();
86 asyncResp->res.jsonValue["Links"]["Storage"] = std::move(storages);
87 });
88}
89
90/**
Gunnar Millsbeeca0a2019-02-14 16:30:45 -060091 * @brief Retrieves chassis state properties over dbus
92 *
Ed Tanousac106bf2023-06-07 09:24:59 -070093 * @param[in] asyncResp - Shared pointer for completing asynchronous calls.
Gunnar Millsbeeca0a2019-02-14 16:30:45 -060094 *
95 * @return None.
96 */
Ed Tanousac106bf2023-06-07 09:24:59 -070097inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
Gunnar Millsbeeca0a2019-02-14 16:30:45 -060098{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070099 // crow::connections::systemBus->async_method_call(
100 sdbusplus::asio::getProperty<std::string>(
101 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
102 "/xyz/openbmc_project/state/chassis0",
103 "xyz.openbmc_project.State.Chassis", "CurrentPowerState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700104 [asyncResp{std::move(asyncResp)}](const boost::system::error_code& ec,
105 const std::string& chassisState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700106 if (ec)
107 {
108 if (ec == boost::system::errc::host_unreachable)
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600109 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700110 // Service not available, no error, just don't return
111 // chassis state info
Ed Tanous62598e32023-07-17 17:06:25 -0700112 BMCWEB_LOG_DEBUG("Service not available {}", ec);
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600113 return;
114 }
Ed Tanous62598e32023-07-17 17:06:25 -0700115 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700116 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700117 return;
118 }
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600119
Ed Tanous62598e32023-07-17 17:06:25 -0700120 BMCWEB_LOG_DEBUG("Chassis state: {}", chassisState);
Ed Tanous002d39b2022-05-31 08:59:27 -0700121 // Verify Chassis State
122 if (chassisState == "xyz.openbmc_project.State.Chassis.PowerState.On")
123 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700124 asyncResp->res.jsonValue["PowerState"] = "On";
125 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700126 }
127 else if (chassisState ==
128 "xyz.openbmc_project.State.Chassis.PowerState.Off")
129 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700130 asyncResp->res.jsonValue["PowerState"] = "Off";
131 asyncResp->res.jsonValue["Status"]["State"] = "StandbyOffline";
Ed Tanous002d39b2022-05-31 08:59:27 -0700132 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700133 });
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600134}
135
Ed Tanousac106bf2023-06-07 09:24:59 -0700136inline void getIntrusionByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000137 const std::string& service,
138 const std::string& objPath)
Qiang XUc1819422019-02-27 13:51:32 +0800139{
Ed Tanous62598e32023-07-17 17:06:25 -0700140 BMCWEB_LOG_DEBUG("Get intrusion status by service ");
Qiang XUc1819422019-02-27 13:51:32 +0800141
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700142 sdbusplus::asio::getProperty<std::string>(
143 *crow::connections::systemBus, service, objPath,
144 "xyz.openbmc_project.Chassis.Intrusion", "Status",
Ed Tanousac106bf2023-06-07 09:24:59 -0700145 [asyncResp{std::move(asyncResp)}](const boost::system::error_code& ec,
146 const std::string& value) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700147 if (ec)
148 {
149 // do not add err msg in redfish response, because this is not
150 // mandatory property
Ed Tanous62598e32023-07-17 17:06:25 -0700151 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700152 return;
153 }
Qiang XUc1819422019-02-27 13:51:32 +0800154
Ed Tanousac106bf2023-06-07 09:24:59 -0700155 asyncResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensorNumber"] =
156 1;
157 asyncResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensor"] = value;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700158 });
Qiang XUc1819422019-02-27 13:51:32 +0800159}
160
161/**
162 * Retrieves physical security properties over dbus
163 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700164inline void
165 getPhysicalSecurityData(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
Qiang XUc1819422019-02-27 13:51:32 +0800166{
George Liue99073f2022-12-09 11:06:16 +0800167 constexpr std::array<std::string_view, 1> interfaces = {
168 "xyz.openbmc_project.Chassis.Intrusion"};
169 dbus::utility::getSubTree(
Chau Ly630adcd2023-02-20 07:26:23 +0000170 "/xyz/openbmc_project", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -0700171 [asyncResp{std::move(asyncResp)}](
George Liue99073f2022-12-09 11:06:16 +0800172 const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800173 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700174 if (ec)
175 {
176 // do not add err msg in redfish response, because this is not
177 // mandatory property
Ed Tanous62598e32023-07-17 17:06:25 -0700178 BMCWEB_LOG_INFO("DBUS error: no matched iface {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700179 return;
180 }
181 // Iterate over all retrieved ObjectPaths.
182 for (const auto& object : subtree)
183 {
Patrick Williams840a9ff2023-05-12 10:18:43 -0500184 if (!object.second.empty())
Qiang XUc1819422019-02-27 13:51:32 +0800185 {
Patrick Williams840a9ff2023-05-12 10:18:43 -0500186 const auto service = object.second.front();
Ed Tanousac106bf2023-06-07 09:24:59 -0700187 getIntrusionByService(asyncResp, service.first, object.first);
Qiang XUc1819422019-02-27 13:51:32 +0800188 return;
189 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700190 }
George Liue99073f2022-12-09 11:06:16 +0800191 });
Qiang XUc1819422019-02-27 13:51:32 +0800192}
193
Nan Zhoucf7eba02022-07-21 23:53:20 +0000194inline void handleChassisCollectionGet(
195 App& app, const crow::Request& req,
196 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
197{
198 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
199 {
200 return;
201 }
202 asyncResp->res.jsonValue["@odata.type"] =
203 "#ChassisCollection.ChassisCollection";
204 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
205 asyncResp->res.jsonValue["Name"] = "Chassis Collection";
206
George Liu7a1dbc42022-12-07 16:03:22 +0800207 constexpr std::array<std::string_view, 2> interfaces{
208 "xyz.openbmc_project.Inventory.Item.Board",
209 "xyz.openbmc_project.Inventory.Item.Chassis"};
Nan Zhoucf7eba02022-07-21 23:53:20 +0000210 collection_util::getCollectionMembers(
George Liu7a1dbc42022-12-07 16:03:22 +0800211 asyncResp, boost::urls::url("/redfish/v1/Chassis"), interfaces);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000212}
213
Jie Yanga5617492021-06-29 12:59:14 -0700214inline void getChassisContainedBy(
215 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
216 const std::string& chassisId, const boost::system::error_code& ec,
217 const dbus::utility::MapperEndPoints& upstreamChassisPaths)
218{
219 if (ec)
220 {
221 if (ec.value() != EBADR)
222 {
Ed Tanous62598e32023-07-17 17:06:25 -0700223 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Jie Yanga5617492021-06-29 12:59:14 -0700224 messages::internalError(asyncResp->res);
225 }
226 return;
227 }
228 if (upstreamChassisPaths.empty())
229 {
230 return;
231 }
232 if (upstreamChassisPaths.size() > 1)
233 {
Ed Tanous62598e32023-07-17 17:06:25 -0700234 BMCWEB_LOG_ERROR("{} is contained by mutliple chassis", chassisId);
Jie Yanga5617492021-06-29 12:59:14 -0700235 messages::internalError(asyncResp->res);
236 return;
237 }
238
239 sdbusplus::message::object_path upstreamChassisPath(
240 upstreamChassisPaths[0]);
241 std::string upstreamChassis = upstreamChassisPath.filename();
242 if (upstreamChassis.empty())
243 {
Ed Tanous62598e32023-07-17 17:06:25 -0700244 BMCWEB_LOG_WARNING("Malformed upstream Chassis path {} on {}",
245 upstreamChassisPath.str, chassisId);
Jie Yanga5617492021-06-29 12:59:14 -0700246 return;
247 }
248
249 asyncResp->res.jsonValue["Links"]["ContainedBy"]["@odata.id"] =
250 boost::urls::format("/redfish/v1/Chassis/{}", upstreamChassis);
251}
252
253inline void getChassisContains(
254 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
255 const std::string& chassisId, const boost::system::error_code& ec,
256 const dbus::utility::MapperEndPoints& downstreamChassisPaths)
257{
258 if (ec)
259 {
260 if (ec.value() != EBADR)
261 {
Ed Tanous62598e32023-07-17 17:06:25 -0700262 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Jie Yanga5617492021-06-29 12:59:14 -0700263 messages::internalError(asyncResp->res);
264 }
265 return;
266 }
267 if (downstreamChassisPaths.empty())
268 {
269 return;
270 }
271 nlohmann::json& jValue = asyncResp->res.jsonValue["Links"]["Contains"];
272 if (!jValue.is_array())
273 {
274 // Create the array if it was empty
275 jValue = nlohmann::json::array();
276 }
277 for (const auto& p : downstreamChassisPaths)
278 {
279 sdbusplus::message::object_path downstreamChassisPath(p);
280 std::string downstreamChassis = downstreamChassisPath.filename();
281 if (downstreamChassis.empty())
282 {
Ed Tanous62598e32023-07-17 17:06:25 -0700283 BMCWEB_LOG_WARNING("Malformed downstream Chassis path {} on {}",
284 downstreamChassisPath.str, chassisId);
Jie Yanga5617492021-06-29 12:59:14 -0700285 continue;
286 }
287 nlohmann::json link;
288 link["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
289 downstreamChassis);
290 jValue.push_back(std::move(link));
291 }
292 asyncResp->res.jsonValue["Links"]["Contains@odata.count"] = jValue.size();
293}
294
295inline void
296 getChassisConnectivity(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
297 const std::string& chassisId,
298 const std::string& chassisPath)
299{
Ed Tanous62598e32023-07-17 17:06:25 -0700300 BMCWEB_LOG_DEBUG("Get chassis connectivity");
Jie Yanga5617492021-06-29 12:59:14 -0700301
302 dbus::utility::getAssociationEndPoints(
303 chassisPath + "/contained_by",
304 std::bind_front(getChassisContainedBy, asyncResp, chassisId));
305
306 dbus::utility::getAssociationEndPoints(
307 chassisPath + "/containing",
308 std::bind_front(getChassisContains, asyncResp, chassisId));
309}
310
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100311/**
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100312 * ChassisCollection derived class for delivering Chassis Collection Schema
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700313 * Functions triggers appropriate requests on DBus
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100314 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700315inline void requestRoutesChassisCollection(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700316{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700317 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/")
Ed Tanoused398212021-06-09 17:05:54 -0700318 .privileges(redfish::privileges::getChassisCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700319 .methods(boost::beast::http::verb::get)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000320 std::bind_front(handleChassisCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700321}
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100322
Willy Tu308f70c2021-09-28 20:24:52 -0700323inline void
324 getChassisLocationCode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
325 const std::string& connectionName,
326 const std::string& path)
327{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700328 sdbusplus::asio::getProperty<std::string>(
329 *crow::connections::systemBus, connectionName, path,
330 "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800331 [asyncResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700332 const std::string& property) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700333 if (ec)
334 {
Ed Tanous62598e32023-07-17 17:06:25 -0700335 BMCWEB_LOG_ERROR("DBUS response error for Location");
Ed Tanous002d39b2022-05-31 08:59:27 -0700336 messages::internalError(asyncResp->res);
337 return;
338 }
Willy Tu308f70c2021-09-28 20:24:52 -0700339
Ed Tanous002d39b2022-05-31 08:59:27 -0700340 asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
341 property;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700342 });
Willy Tu308f70c2021-09-28 20:24:52 -0700343}
344
345inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
346 const std::string& connectionName,
347 const std::string& path)
348{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700349 sdbusplus::asio::getProperty<std::string>(
350 *crow::connections::systemBus, connectionName, path,
351 "xyz.openbmc_project.Common.UUID", "UUID",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800352 [asyncResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700353 const std::string& chassisUUID) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700354 if (ec)
355 {
Ed Tanous62598e32023-07-17 17:06:25 -0700356 BMCWEB_LOG_ERROR("DBUS response error for UUID");
Ed Tanous002d39b2022-05-31 08:59:27 -0700357 messages::internalError(asyncResp->res);
358 return;
359 }
360 asyncResp->res.jsonValue["UUID"] = chassisUUID;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700361 });
Willy Tu308f70c2021-09-28 20:24:52 -0700362}
363
Nan Zhoucf7eba02022-07-21 23:53:20 +0000364inline void
365 handleChassisGet(App& app, const crow::Request& req,
366 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
367 const std::string& chassisId)
368{
369 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
370 {
371 return;
372 }
George Liue99073f2022-12-09 11:06:16 +0800373 constexpr std::array<std::string_view, 2> interfaces = {
Nan Zhoucf7eba02022-07-21 23:53:20 +0000374 "xyz.openbmc_project.Inventory.Item.Board",
375 "xyz.openbmc_project.Inventory.Item.Chassis"};
376
George Liue99073f2022-12-09 11:06:16 +0800377 dbus::utility::getSubTree(
378 "/xyz/openbmc_project/inventory", 0, interfaces,
Nan Zhoucf7eba02022-07-21 23:53:20 +0000379 [asyncResp, chassisId(std::string(chassisId))](
George Liue99073f2022-12-09 11:06:16 +0800380 const boost::system::error_code& ec,
Nan Zhoucf7eba02022-07-21 23:53:20 +0000381 const dbus::utility::MapperGetSubTreeResponse& subtree) {
382 if (ec)
383 {
Ed Tanous62598e32023-07-17 17:06:25 -0700384 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000385 messages::internalError(asyncResp->res);
386 return;
387 }
388 // Iterate over all retrieved ObjectPaths.
389 for (const std::pair<
390 std::string,
391 std::vector<std::pair<std::string, std::vector<std::string>>>>&
392 object : subtree)
393 {
394 const std::string& path = object.first;
395 const std::vector<std::pair<std::string, std::vector<std::string>>>&
396 connectionNames = object.second;
397
398 sdbusplus::message::object_path objPath(path);
399 if (objPath.filename() != chassisId)
400 {
401 continue;
402 }
403
Jie Yanga5617492021-06-29 12:59:14 -0700404 getChassisConnectivity(asyncResp, chassisId, path);
405
Nan Zhoucf7eba02022-07-21 23:53:20 +0000406 auto health = std::make_shared<HealthPopulate>(asyncResp);
407
Willy Tu13451e32023-05-24 16:08:18 -0700408 if constexpr (bmcwebEnableHealthPopulate)
409 {
410 dbus::utility::getAssociationEndPoints(
411 path + "/all_sensors",
412 [health](const boost::system::error_code& ec2,
413 const dbus::utility::MapperEndPoints& resp) {
414 if (ec2)
415 {
416 return; // no sensors = no failures
417 }
418 health->inventory = resp;
419 });
Nan Zhoucf7eba02022-07-21 23:53:20 +0000420
Willy Tu13451e32023-05-24 16:08:18 -0700421 health->populate();
422 }
Nan Zhoucf7eba02022-07-21 23:53:20 +0000423
424 if (connectionNames.empty())
425 {
Ed Tanous62598e32023-07-17 17:06:25 -0700426 BMCWEB_LOG_ERROR("Got 0 Connection names");
Nan Zhoucf7eba02022-07-21 23:53:20 +0000427 continue;
428 }
429
430 asyncResp->res.jsonValue["@odata.type"] =
Logananth Sundararaj523d4862023-01-24 11:56:28 +0530431 "#Chassis.v1_22_0.Chassis";
Nan Zhoucf7eba02022-07-21 23:53:20 +0000432 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700433 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000434 asyncResp->res.jsonValue["Name"] = "Chassis Collection";
435 asyncResp->res.jsonValue["ChassisType"] = "RackMount";
436 asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]["target"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700437 boost::urls::format(
438 "/redfish/v1/Chassis/{}/Actions/Chassis.Reset", chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000439 asyncResp->res
440 .jsonValue["Actions"]["#Chassis.Reset"]["@Redfish.ActionInfo"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700441 boost::urls::format("/redfish/v1/Chassis/{}/ResetActionInfo",
442 chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000443 asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700444 "/redfish/v1/Systems/system/PCIeDevices";
Nan Zhoucf7eba02022-07-21 23:53:20 +0000445
George Liu6c3e9452023-03-03 13:55:29 +0800446 dbus::utility::getAssociationEndPoints(
447 path + "/drive",
448 [asyncResp,
449 chassisId](const boost::system::error_code& ec3,
450 const dbus::utility::MapperEndPoints& resp) {
Nan Zhoucf7eba02022-07-21 23:53:20 +0000451 if (ec3 || resp.empty())
452 {
453 return; // no drives = no failures
454 }
455
456 nlohmann::json reference;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700457 reference["@odata.id"] = boost::urls::format(
458 "/redfish/v1/Chassis/{}/Drives", chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000459 asyncResp->res.jsonValue["Drives"] = std::move(reference);
460 });
461
462 const std::string& connectionName = connectionNames[0].first;
463
464 const std::vector<std::string>& interfaces2 =
465 connectionNames[0].second;
466 const std::array<const char*, 2> hasIndicatorLed = {
467 "xyz.openbmc_project.Inventory.Item.Panel",
468 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
469
470 const std::string assetTagInterface =
471 "xyz.openbmc_project.Inventory.Decorator.AssetTag";
Logananth Sundararaj523d4862023-01-24 11:56:28 +0530472 const std::string replaceableInterface =
473 "xyz.openbmc_project.Inventory.Decorator.Replaceable";
474 for (const auto& interface : interfaces2)
Nan Zhoucf7eba02022-07-21 23:53:20 +0000475 {
Logananth Sundararaj523d4862023-01-24 11:56:28 +0530476 if (interface == assetTagInterface)
477 {
478 sdbusplus::asio::getProperty<std::string>(
479 *crow::connections::systemBus, connectionName, path,
480 assetTagInterface, "AssetTag",
481 [asyncResp,
482 chassisId](const boost::system::error_code& ec2,
483 const std::string& property) {
484 if (ec2)
485 {
Ed Tanous62598e32023-07-17 17:06:25 -0700486 BMCWEB_LOG_ERROR(
487 "DBus response error for AssetTag: {}", ec2);
Logananth Sundararaj523d4862023-01-24 11:56:28 +0530488 messages::internalError(asyncResp->res);
489 return;
490 }
491 asyncResp->res.jsonValue["AssetTag"] = property;
492 });
493 }
494 else if (interface == replaceableInterface)
495 {
496 sdbusplus::asio::getProperty<bool>(
497 *crow::connections::systemBus, connectionName, path,
498 replaceableInterface, "HotPluggable",
499 [asyncResp,
500 chassisId](const boost::system::error_code& ec2,
501 const bool property) {
502 if (ec2)
503 {
Ed Tanous62598e32023-07-17 17:06:25 -0700504 BMCWEB_LOG_ERROR(
505 "DBus response error for HotPluggable: {}",
506 ec2);
Logananth Sundararaj523d4862023-01-24 11:56:28 +0530507 messages::internalError(asyncResp->res);
508 return;
509 }
510 asyncResp->res.jsonValue["HotPluggable"] = property;
511 });
512 }
Nan Zhoucf7eba02022-07-21 23:53:20 +0000513 }
514
515 for (const char* interface : hasIndicatorLed)
516 {
517 if (std::find(interfaces2.begin(), interfaces2.end(),
518 interface) != interfaces2.end())
519 {
520 getIndicatorLedState(asyncResp);
521 getLocationIndicatorActive(asyncResp);
522 break;
523 }
524 }
525
Krzysztof Grobelny86d89ed2022-08-29 14:49:20 +0200526 sdbusplus::asio::getAllProperties(
527 *crow::connections::systemBus, connectionName, path,
528 "xyz.openbmc_project.Inventory.Decorator.Asset",
Willy Tu5e577bc2022-07-26 00:41:55 +0000529 [asyncResp, chassisId(std::string(chassisId)),
530 path](const boost::system::error_code& /*ec2*/,
531 const dbus::utility::DBusPropertiesMap& propertiesList) {
Krzysztof Grobelny86d89ed2022-08-29 14:49:20 +0200532 const std::string* partNumber = nullptr;
533 const std::string* serialNumber = nullptr;
534 const std::string* manufacturer = nullptr;
535 const std::string* model = nullptr;
536 const std::string* sparePartNumber = nullptr;
537
538 const bool success = sdbusplus::unpackPropertiesNoThrow(
539 dbus_utils::UnpackErrorPrinter(), propertiesList,
540 "PartNumber", partNumber, "SerialNumber", serialNumber,
541 "Manufacturer", manufacturer, "Model", model,
542 "SparePartNumber", sparePartNumber);
543
544 if (!success)
Nan Zhoucf7eba02022-07-21 23:53:20 +0000545 {
Krzysztof Grobelny86d89ed2022-08-29 14:49:20 +0200546 messages::internalError(asyncResp->res);
547 return;
Nan Zhoucf7eba02022-07-21 23:53:20 +0000548 }
Krzysztof Grobelny86d89ed2022-08-29 14:49:20 +0200549
550 if (partNumber != nullptr)
551 {
552 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
553 }
554
555 if (serialNumber != nullptr)
556 {
557 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
558 }
559
560 if (manufacturer != nullptr)
561 {
562 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
563 }
564
565 if (model != nullptr)
566 {
567 asyncResp->res.jsonValue["Model"] = *model;
568 }
569
570 // SparePartNumber is optional on D-Bus
571 // so skip if it is empty
572 if (sparePartNumber != nullptr && !sparePartNumber->empty())
573 {
574 asyncResp->res.jsonValue["SparePartNumber"] =
575 *sparePartNumber;
576 }
577
Nan Zhoucf7eba02022-07-21 23:53:20 +0000578 asyncResp->res.jsonValue["Name"] = chassisId;
579 asyncResp->res.jsonValue["Id"] = chassisId;
580#ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL
581 asyncResp->res.jsonValue["Thermal"]["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700582 boost::urls::format("/redfish/v1/Chassis/{}/Thermal",
583 chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000584 // Power object
585 asyncResp->res.jsonValue["Power"]["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700586 boost::urls::format("/redfish/v1/Chassis/{}/Power",
587 chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000588#endif
Xiaochao Ma29739632021-03-02 15:53:13 +0800589#ifdef BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM
590 asyncResp->res.jsonValue["ThermalSubsystem"]["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700591 boost::urls::format(
592 "/redfish/v1/Chassis/{}/ThermalSubsystem", chassisId);
Chicago Duan77b36432021-02-05 15:48:26 +0800593 asyncResp->res.jsonValue["PowerSubsystem"]["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700594 boost::urls::format("/redfish/v1/Chassis/{}/PowerSubsystem",
595 chassisId);
Albert Zhang4ca3ec32021-06-13 14:39:38 +0800596 asyncResp->res.jsonValue["EnvironmentMetrics"]["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700597 boost::urls::format(
598 "/redfish/v1/Chassis/{}/EnvironmentMetrics", chassisId);
Xiaochao Ma29739632021-03-02 15:53:13 +0800599#endif
Nan Zhoucf7eba02022-07-21 23:53:20 +0000600 // SensorCollection
601 asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700602 boost::urls::format("/redfish/v1/Chassis/{}/Sensors",
603 chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000604 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
605
606 nlohmann::json::array_t computerSystems;
607 nlohmann::json::object_t system;
608 system["@odata.id"] = "/redfish/v1/Systems/system";
Patrick Williamsad539542023-05-12 10:10:08 -0500609 computerSystems.emplace_back(std::move(system));
Nan Zhoucf7eba02022-07-21 23:53:20 +0000610 asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
611 std::move(computerSystems);
612
613 nlohmann::json::array_t managedBy;
614 nlohmann::json::object_t manager;
615 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
Patrick Williamsad539542023-05-12 10:10:08 -0500616 managedBy.emplace_back(std::move(manager));
Nan Zhoucf7eba02022-07-21 23:53:20 +0000617 asyncResp->res.jsonValue["Links"]["ManagedBy"] =
618 std::move(managedBy);
619 getChassisState(asyncResp);
Willy Tu5e577bc2022-07-26 00:41:55 +0000620 getStorageLink(asyncResp, path);
Krzysztof Grobelny86d89ed2022-08-29 14:49:20 +0200621 });
Nan Zhoucf7eba02022-07-21 23:53:20 +0000622
623 for (const auto& interface : interfaces2)
624 {
625 if (interface == "xyz.openbmc_project.Common.UUID")
626 {
627 getChassisUUID(asyncResp, connectionName, path);
628 }
629 else if (interface ==
630 "xyz.openbmc_project.Inventory.Decorator.LocationCode")
631 {
632 getChassisLocationCode(asyncResp, connectionName, path);
633 }
634 }
635
636 return;
637 }
638
639 // Couldn't find an object with that name. return an error
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800640 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
George Liue99073f2022-12-09 11:06:16 +0800641 });
Nan Zhoucf7eba02022-07-21 23:53:20 +0000642
643 getPhysicalSecurityData(asyncResp);
644}
645
646inline void
647 handleChassisPatch(App& app, const crow::Request& req,
648 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
649 const std::string& param)
650{
651 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
652 {
653 return;
654 }
655 std::optional<bool> locationIndicatorActive;
656 std::optional<std::string> indicatorLed;
657
658 if (param.empty())
659 {
660 return;
661 }
662
663 if (!json_util::readJsonPatch(
664 req, asyncResp->res, "LocationIndicatorActive",
665 locationIndicatorActive, "IndicatorLED", indicatorLed))
666 {
667 return;
668 }
669
670 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
671 if (!locationIndicatorActive && !indicatorLed)
672 {
673 return; // delete this when we support more patch properties
674 }
675 if (indicatorLed)
676 {
677 asyncResp->res.addHeader(
678 boost::beast::http::field::warning,
679 "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
680 }
681
George Liue99073f2022-12-09 11:06:16 +0800682 constexpr std::array<std::string_view, 2> interfaces = {
Nan Zhoucf7eba02022-07-21 23:53:20 +0000683 "xyz.openbmc_project.Inventory.Item.Board",
684 "xyz.openbmc_project.Inventory.Item.Chassis"};
685
686 const std::string& chassisId = param;
687
George Liue99073f2022-12-09 11:06:16 +0800688 dbus::utility::getSubTree(
689 "/xyz/openbmc_project/inventory", 0, interfaces,
Nan Zhoucf7eba02022-07-21 23:53:20 +0000690 [asyncResp, chassisId, locationIndicatorActive,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800691 indicatorLed](const boost::system::error_code& ec,
Nan Zhoucf7eba02022-07-21 23:53:20 +0000692 const dbus::utility::MapperGetSubTreeResponse& subtree) {
693 if (ec)
694 {
Ed Tanous62598e32023-07-17 17:06:25 -0700695 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000696 messages::internalError(asyncResp->res);
697 return;
698 }
699
700 // Iterate over all retrieved ObjectPaths.
701 for (const std::pair<
702 std::string,
703 std::vector<std::pair<std::string, std::vector<std::string>>>>&
704 object : subtree)
705 {
706 const std::string& path = object.first;
707 const std::vector<std::pair<std::string, std::vector<std::string>>>&
708 connectionNames = object.second;
709
710 sdbusplus::message::object_path objPath(path);
711 if (objPath.filename() != chassisId)
712 {
713 continue;
714 }
715
716 if (connectionNames.empty())
717 {
Ed Tanous62598e32023-07-17 17:06:25 -0700718 BMCWEB_LOG_ERROR("Got 0 Connection names");
Nan Zhoucf7eba02022-07-21 23:53:20 +0000719 continue;
720 }
721
722 const std::vector<std::string>& interfaces3 =
723 connectionNames[0].second;
724
725 const std::array<const char*, 2> hasIndicatorLed = {
726 "xyz.openbmc_project.Inventory.Item.Panel",
727 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
728 bool indicatorChassis = false;
729 for (const char* interface : hasIndicatorLed)
730 {
731 if (std::find(interfaces3.begin(), interfaces3.end(),
732 interface) != interfaces3.end())
733 {
734 indicatorChassis = true;
735 break;
736 }
737 }
738 if (locationIndicatorActive)
739 {
740 if (indicatorChassis)
741 {
742 setLocationIndicatorActive(asyncResp,
743 *locationIndicatorActive);
744 }
745 else
746 {
747 messages::propertyUnknown(asyncResp->res,
748 "LocationIndicatorActive");
749 }
750 }
751 if (indicatorLed)
752 {
753 if (indicatorChassis)
754 {
755 setIndicatorLedState(asyncResp, *indicatorLed);
756 }
757 else
758 {
759 messages::propertyUnknown(asyncResp->res, "IndicatorLED");
760 }
761 }
762 return;
763 }
764
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800765 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
George Liue99073f2022-12-09 11:06:16 +0800766 });
Nan Zhoucf7eba02022-07-21 23:53:20 +0000767}
768
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100769/**
770 * Chassis override class for delivering Chassis Schema
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700771 * Functions triggers appropriate requests on DBus
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100772 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700773inline void requestRoutesChassis(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700774{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700775 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700776 .privileges(redfish::privileges::getChassis)
Ed Tanous002d39b2022-05-31 08:59:27 -0700777 .methods(boost::beast::http::verb::get)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000778 std::bind_front(handleChassisGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700779
780 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700781 .privileges(redfish::privileges::patchChassis)
Ed Tanous002d39b2022-05-31 08:59:27 -0700782 .methods(boost::beast::http::verb::patch)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000783 std::bind_front(handleChassisPatch, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700784}
P.K. Leedd99e042020-06-17 19:43:16 +0800785
Andrew Geisslerfc903b32023-05-31 14:15:42 -0400786/**
787 * Handle error responses from d-bus for chassis power cycles
788 */
789inline void handleChassisPowerCycleError(const boost::system::error_code& ec,
790 const sdbusplus::message_t& eMsg,
791 crow::Response& res)
792{
793 if (eMsg.get_error() == nullptr)
794 {
Ed Tanous62598e32023-07-17 17:06:25 -0700795 BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
Andrew Geisslerfc903b32023-05-31 14:15:42 -0400796 messages::internalError(res);
797 return;
798 }
799 std::string_view errorMessage = eMsg.get_error()->name;
800
801 // If operation failed due to BMC not being in Ready state, tell
802 // user to retry in a bit
803 if (errorMessage ==
804 std::string_view("xyz.openbmc_project.State.Chassis.Error.BMCNotReady"))
805 {
Ed Tanous62598e32023-07-17 17:06:25 -0700806 BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
Andrew Geisslerfc903b32023-05-31 14:15:42 -0400807 messages::serviceTemporarilyUnavailable(res, "10");
808 return;
809 }
810
Ed Tanous62598e32023-07-17 17:06:25 -0700811 BMCWEB_LOG_ERROR("Chassis Power Cycle fail {} sdbusplus:{}", ec,
812 errorMessage);
Andrew Geisslerfc903b32023-05-31 14:15:42 -0400813 messages::internalError(res);
814}
815
zhanghch058d1b46d2021-04-01 11:18:24 +0800816inline void
817 doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
P.K. Leedd99e042020-06-17 19:43:16 +0800818{
George Liu7a1dbc42022-12-07 16:03:22 +0800819 constexpr std::array<std::string_view, 1> interfaces = {
Vijay Khemkac3b3c922020-09-22 23:00:12 -0700820 "xyz.openbmc_project.State.Chassis"};
821
822 // Use mapper to get subtree paths.
George Liu7a1dbc42022-12-07 16:03:22 +0800823 dbus::utility::getSubTreePaths(
824 "/", 0, interfaces,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800825 [asyncResp](
George Liu7a1dbc42022-12-07 16:03:22 +0800826 const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800827 const dbus::utility::MapperGetSubTreePathsResponse& chassisList) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700828 if (ec)
829 {
Ed Tanous62598e32023-07-17 17:06:25 -0700830 BMCWEB_LOG_ERROR("[mapper] Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700831 messages::internalError(asyncResp->res);
832 return;
833 }
834
835 const char* processName = "xyz.openbmc_project.State.Chassis";
836 const char* interfaceName = "xyz.openbmc_project.State.Chassis";
837 const char* destProperty = "RequestedPowerTransition";
838 const std::string propertyValue =
839 "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
840 std::string objectPath = "/xyz/openbmc_project/state/chassis_system0";
841
842 /* Look for system reset chassis path */
843 if ((std::find(chassisList.begin(), chassisList.end(), objectPath)) ==
844 chassisList.end())
845 {
846 /* We prefer to reset the full chassis_system, but if it doesn't
847 * exist on some platforms, fall back to a host-only power reset
848 */
849 objectPath = "/xyz/openbmc_project/state/chassis0";
850 }
851
George Liu9ae226f2023-06-21 17:56:46 +0800852 sdbusplus::asio::setProperty(
853 *crow::connections::systemBus, processName, objectPath,
854 interfaceName, destProperty, propertyValue,
Andrew Geisslerfc903b32023-05-31 14:15:42 -0400855 [asyncResp](const boost::system::error_code& ec2,
856 sdbusplus::message_t& sdbusErrMsg) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700857 // Use "Set" method to set the property value.
Ed Tanous8a592812022-06-04 09:06:59 -0700858 if (ec2)
P.K. Leedd99e042020-06-17 19:43:16 +0800859 {
Andrew Geisslerfc903b32023-05-31 14:15:42 -0400860 handleChassisPowerCycleError(ec2, sdbusErrMsg, asyncResp->res);
861
P.K. Leedd99e042020-06-17 19:43:16 +0800862 return;
863 }
864
Ed Tanous002d39b2022-05-31 08:59:27 -0700865 messages::success(asyncResp->res);
George Liu9ae226f2023-06-21 17:56:46 +0800866 });
George Liu7a1dbc42022-12-07 16:03:22 +0800867 });
P.K. Leedd99e042020-06-17 19:43:16 +0800868}
869
Nan Zhoucf7eba02022-07-21 23:53:20 +0000870inline void handleChassisResetActionInfoPost(
871 App& app, const crow::Request& req,
872 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
873 const std::string& /*chassisId*/)
874{
875 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
876 {
877 return;
878 }
Ed Tanous62598e32023-07-17 17:06:25 -0700879 BMCWEB_LOG_DEBUG("Post Chassis Reset.");
Nan Zhoucf7eba02022-07-21 23:53:20 +0000880
881 std::string resetType;
882
883 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
884 {
885 return;
886 }
887
888 if (resetType != "PowerCycle")
889 {
Ed Tanous62598e32023-07-17 17:06:25 -0700890 BMCWEB_LOG_DEBUG("Invalid property value for ResetType: {}", resetType);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000891 messages::actionParameterNotSupported(asyncResp->res, resetType,
892 "ResetType");
893
894 return;
895 }
896 doChassisPowerCycle(asyncResp);
897}
898
P.K. Leedd99e042020-06-17 19:43:16 +0800899/**
900 * ChassisResetAction class supports the POST method for the Reset
901 * action.
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700902 * Function handles POST method request.
903 * Analyzes POST body before sending Reset request data to D-Bus.
P.K. Leedd99e042020-06-17 19:43:16 +0800904 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700905
906inline void requestRoutesChassisResetAction(App& app)
P.K. Leedd99e042020-06-17 19:43:16 +0800907{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700908 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -0700909 .privileges(redfish::privileges::postChassis)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700910 .methods(boost::beast::http::verb::post)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000911 std::bind_front(handleChassisResetActionInfoPost, std::ref(app)));
912}
P.K. Leedd99e042020-06-17 19:43:16 +0800913
Nan Zhoucf7eba02022-07-21 23:53:20 +0000914inline void handleChassisResetActionInfoGet(
915 App& app, const crow::Request& req,
916 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
917 const std::string& chassisId)
918{
919 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
920 {
921 return;
922 }
923 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700924 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
925 "/redfish/v1/Chassis/{}/ResetActionInfo", chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000926 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
P.K. Leedd99e042020-06-17 19:43:16 +0800927
Nan Zhoucf7eba02022-07-21 23:53:20 +0000928 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
929 nlohmann::json::array_t parameters;
930 nlohmann::json::object_t parameter;
931 parameter["Name"] = "ResetType";
932 parameter["Required"] = true;
933 parameter["DataType"] = "String";
934 nlohmann::json::array_t allowed;
Patrick Williamsad539542023-05-12 10:10:08 -0500935 allowed.emplace_back("PowerCycle");
Nan Zhoucf7eba02022-07-21 23:53:20 +0000936 parameter["AllowableValues"] = std::move(allowed);
Patrick Williamsad539542023-05-12 10:10:08 -0500937 parameters.emplace_back(std::move(parameter));
P.K. Leedd99e042020-06-17 19:43:16 +0800938
Nan Zhoucf7eba02022-07-21 23:53:20 +0000939 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700940}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +0530941
942/**
943 * ChassisResetActionInfo derived class for delivering Chassis
944 * ResetType AllowableValues using ResetInfo schema.
945 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700946inline void requestRoutesChassisResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +0530947{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700948 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -0700949 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700950 .methods(boost::beast::http::verb::get)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000951 std::bind_front(handleChassisResetActionInfoGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700952}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +0530953
Ed Tanous1abe55e2018-09-05 08:30:59 -0700954} // namespace redfish