blob: e658e3c2cf7912f936d3231a95a3ffcf2e65e5f6 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Chicago Duan7691cc22021-01-25 19:52:35 +08003#pragma once
4
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08005#include "app.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08006#include "async_resp.hpp"
George Liue99073f2022-12-09 11:06:16 +08007#include "dbus_utility.hpp"
Chicago Duan7691cc22021-01-25 19:52:35 +08008#include "error_messages.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08009#include "generated/enums/pcie_device.hpp"
Ed Tanous4ce2c1b2023-02-10 11:57:54 -080010#include "generated/enums/pcie_slots.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080011#include "http_request.hpp"
12#include "logging.hpp"
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -050013#include "query.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080014#include "registries/privilege_registry.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080015#include "utils/dbus_utils.hpp"
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -050016#include "utils/pcie_util.hpp"
Chicago Duan7691cc22021-01-25 19:52:35 +080017
Ed Tanousd7857202025-01-28 15:32:26 -080018#include <asm-generic/errno.h>
19
20#include <boost/beast/http/verb.hpp>
George Liue99073f2022-12-09 11:06:16 +080021#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070022#include <boost/url/format.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080023#include <nlohmann/json.hpp>
24#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020025#include <sdbusplus/unpack_properties.hpp>
Chicago Duan7691cc22021-01-25 19:52:35 +080026
George Liue99073f2022-12-09 11:06:16 +080027#include <array>
Ed Tanousd7857202025-01-28 15:32:26 -080028#include <cstddef>
29#include <functional>
30#include <memory>
31#include <optional>
32#include <string>
George Liue99073f2022-12-09 11:06:16 +080033#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080034#include <utility>
George Liue99073f2022-12-09 11:06:16 +080035
Chicago Duan7691cc22021-01-25 19:52:35 +080036namespace redfish
37{
38
Patrick Williams504af5a2025-02-03 14:29:03 -050039inline void onPcieSlotGetAllDone(
40 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
41 const boost::system::error_code& ec,
42 const dbus::utility::DBusPropertiesMap& propertiesList)
Chicago Duan7691cc22021-01-25 19:52:35 +080043{
44 if (ec)
45 {
Ed Tanous62598e32023-07-17 17:06:25 -070046 BMCWEB_LOG_ERROR("Can't get PCIeSlot properties!");
Chicago Duan7691cc22021-01-25 19:52:35 +080047 messages::internalError(asyncResp->res);
48 return;
49 }
50
51 nlohmann::json& slots = asyncResp->res.jsonValue["Slots"];
52
53 nlohmann::json::array_t* slotsPtr =
54 slots.get_ptr<nlohmann::json::array_t*>();
55 if (slotsPtr == nullptr)
56 {
Ed Tanous62598e32023-07-17 17:06:25 -070057 BMCWEB_LOG_ERROR("Slots key isn't an array???");
Chicago Duan7691cc22021-01-25 19:52:35 +080058 messages::internalError(asyncResp->res);
59 return;
60 }
61
62 nlohmann::json::object_t slot;
63
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020064 const std::string* generation = nullptr;
65 const size_t* lanes = nullptr;
66 const std::string* slotType = nullptr;
67 const bool* hotPluggable = nullptr;
Chicago Duan7691cc22021-01-25 19:52:35 +080068
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020069 const bool success = sdbusplus::unpackPropertiesNoThrow(
70 dbus_utils::UnpackErrorPrinter(), propertiesList, "Generation",
71 generation, "Lanes", lanes, "SlotType", slotType, "HotPluggable",
72 hotPluggable);
73
74 if (!success)
75 {
76 messages::internalError(asyncResp->res);
77 return;
Chicago Duan7691cc22021-01-25 19:52:35 +080078 }
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020079
80 if (generation != nullptr)
81 {
Ed Tanous0ec8b832022-03-14 14:56:47 -070082 std::optional<pcie_device::PCIeTypes> pcieType =
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -050083 pcie_util::redfishPcieGenerationFromDbus(*generation);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020084 if (!pcieType)
85 {
Ed Tanous62598e32023-07-17 17:06:25 -070086 BMCWEB_LOG_WARNING("Unknown PCIe Slot Generation: {}", *generation);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020087 }
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -050088 else
Lakshmi Yadlapatibbf372a2023-05-02 15:09:08 -050089 {
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -050090 if (*pcieType == pcie_device::PCIeTypes::Invalid)
91 {
92 messages::internalError(asyncResp->res);
93 return;
94 }
Lakshmi Yadlapatibbf372a2023-05-02 15:09:08 -050095 slot["PCIeType"] = *pcieType;
96 }
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020097 }
98
Konstantin Aladyshev82f80322023-07-10 15:00:38 +030099 if (lanes != nullptr && *lanes != 0)
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200100 {
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200101 slot["Lanes"] = *lanes;
102 }
103
104 if (slotType != nullptr)
105 {
Lakshmi Yadlapatid87fdd92023-05-02 16:50:31 -0500106 std::optional<pcie_slots::SlotTypes> redfishSlotType =
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -0500107 pcie_util::dbusSlotTypeToRf(*slotType);
Lakshmi Yadlapatid87fdd92023-05-02 16:50:31 -0500108 if (!redfishSlotType)
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200109 {
Ed Tanous62598e32023-07-17 17:06:25 -0700110 BMCWEB_LOG_WARNING("Unknown PCIe Slot Type: {}", *slotType);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200111 }
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500112 else
Lakshmi Yadlapatid87fdd92023-05-02 16:50:31 -0500113 {
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500114 if (*redfishSlotType == pcie_slots::SlotTypes::Invalid)
115 {
Ed Tanous62598e32023-07-17 17:06:25 -0700116 BMCWEB_LOG_ERROR("Unknown PCIe Slot Type: {}", *slotType);
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500117 messages::internalError(asyncResp->res);
118 return;
119 }
Lakshmi Yadlapatid87fdd92023-05-02 16:50:31 -0500120 slot["SlotType"] = *redfishSlotType;
121 }
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200122 }
123
124 if (hotPluggable != nullptr)
125 {
126 slot["HotPluggable"] = *hotPluggable;
127 }
128
Chicago Duan7691cc22021-01-25 19:52:35 +0800129 slots.emplace_back(std::move(slot));
130}
131
132inline void onMapperAssociationDone(
133 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
134 const std::string& chassisID, const std::string& pcieSlotPath,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800135 const std::string& connectionName, const boost::system::error_code& ec,
George Liu6c3e9452023-03-03 13:55:29 +0800136 const dbus::utility::MapperEndPoints& pcieSlotChassis)
Chicago Duan7691cc22021-01-25 19:52:35 +0800137{
138 if (ec)
139 {
140 if (ec.value() == EBADR)
141 {
142 // This PCIeSlot have no chassis association.
143 return;
144 }
Ed Tanous62598e32023-07-17 17:06:25 -0700145 BMCWEB_LOG_ERROR("DBUS response error");
Chicago Duan7691cc22021-01-25 19:52:35 +0800146 messages::internalError(asyncResp->res);
147 return;
148 }
149
George Liu6c3e9452023-03-03 13:55:29 +0800150 if (pcieSlotChassis.size() != 1)
Chicago Duan7691cc22021-01-25 19:52:35 +0800151 {
Ed Tanous62598e32023-07-17 17:06:25 -0700152 BMCWEB_LOG_ERROR("PCIe Slot association error! ");
Chicago Duan7691cc22021-01-25 19:52:35 +0800153 messages::internalError(asyncResp->res);
154 return;
155 }
156
George Liu6c3e9452023-03-03 13:55:29 +0800157 sdbusplus::message::object_path path(pcieSlotChassis[0]);
Chicago Duan7691cc22021-01-25 19:52:35 +0800158 std::string chassisName = path.filename();
159 if (chassisName != chassisID)
160 {
161 // The pcie slot doesn't belong to the chassisID
162 return;
163 }
164
Ed Tanousdeae6a72024-11-11 21:58:57 -0800165 dbus::utility::getAllProperties(
166 connectionName, pcieSlotPath,
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200167 "xyz.openbmc_project.Inventory.Item.PCIeSlot",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800168 [asyncResp](const boost::system::error_code& ec2,
Chicago Duan7691cc22021-01-25 19:52:35 +0800169 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400170 onPcieSlotGetAllDone(asyncResp, ec2, propertiesList);
171 });
Chicago Duan7691cc22021-01-25 19:52:35 +0800172}
173
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400174inline void onMapperSubtreeDone(
175 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
176 const std::string& chassisID, const boost::system::error_code& ec,
177 const dbus::utility::MapperGetSubTreeResponse& subtree)
Chicago Duan7691cc22021-01-25 19:52:35 +0800178{
179 if (ec)
180 {
Ed Tanous62598e32023-07-17 17:06:25 -0700181 BMCWEB_LOG_ERROR("D-Bus response error on GetSubTree {}", ec);
Chicago Duan7691cc22021-01-25 19:52:35 +0800182 messages::internalError(asyncResp->res);
183 return;
184 }
185 if (subtree.empty())
186 {
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800187 messages::resourceNotFound(asyncResp->res, "Chassis", chassisID);
Chicago Duan7691cc22021-01-25 19:52:35 +0800188 return;
189 }
190
Ed Tanous62598e32023-07-17 17:06:25 -0700191 BMCWEB_LOG_DEBUG("Get properties for PCIeSlots associated to chassis = {}",
192 chassisID);
Chicago Duan7691cc22021-01-25 19:52:35 +0800193
194 asyncResp->res.jsonValue["@odata.type"] = "#PCIeSlots.v1_4_1.PCIeSlots";
195 asyncResp->res.jsonValue["Name"] = "PCIe Slot Information";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700196 asyncResp->res.jsonValue["@odata.id"] =
197 boost::urls::format("/redfish/v1/Chassis/{}/PCIeSlots", chassisID);
Chicago Duan7691cc22021-01-25 19:52:35 +0800198 asyncResp->res.jsonValue["Id"] = "1";
199 asyncResp->res.jsonValue["Slots"] = nlohmann::json::array();
200
201 for (const auto& pathServicePair : subtree)
202 {
203 const std::string& pcieSlotPath = pathServicePair.first;
204 for (const auto& connectionInterfacePair : pathServicePair.second)
205 {
206 const std::string& connectionName = connectionInterfacePair.first;
207 sdbusplus::message::object_path pcieSlotAssociationPath(
208 pcieSlotPath);
209 pcieSlotAssociationPath /= "chassis";
210
211 // The association of this PCIeSlot is used to determine whether
212 // it belongs to this ChassisID
George Liu6c3e9452023-03-03 13:55:29 +0800213 dbus::utility::getAssociationEndPoints(
214 std::string{pcieSlotAssociationPath},
Chicago Duan7691cc22021-01-25 19:52:35 +0800215 [asyncResp, chassisID, pcieSlotPath, connectionName](
Ed Tanous4ce2c1b2023-02-10 11:57:54 -0800216 const boost::system::error_code& ec2,
George Liu6c3e9452023-03-03 13:55:29 +0800217 const dbus::utility::MapperEndPoints& endpoints) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400218 onMapperAssociationDone(asyncResp, chassisID, pcieSlotPath,
219 connectionName, ec2, endpoints);
220 });
Chicago Duan7691cc22021-01-25 19:52:35 +0800221 }
222 }
223}
224
225inline void handlePCIeSlotCollectionGet(
226 crow::App& app, const crow::Request& req,
227 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
228 const std::string& chassisID)
229{
Ed Tanous2aacf852022-06-17 08:07:54 -0700230 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Chicago Duan7691cc22021-01-25 19:52:35 +0800231 {
232 return;
233 }
234
George Liue99073f2022-12-09 11:06:16 +0800235 constexpr std::array<std::string_view, 1> interfaces = {
236 "xyz.openbmc_project.Inventory.Item.PCIeSlot"};
237 dbus::utility::getSubTree(
238 "/xyz/openbmc_project/inventory", 0, interfaces,
Chicago Duan7691cc22021-01-25 19:52:35 +0800239 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +0800240 chassisID](const boost::system::error_code& ec,
Chicago Duan7691cc22021-01-25 19:52:35 +0800241 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400242 onMapperSubtreeDone(asyncResp, chassisID, ec, subtree);
243 });
Chicago Duan7691cc22021-01-25 19:52:35 +0800244}
245
246inline void requestRoutesPCIeSlots(App& app)
247{
248 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PCIeSlots/")
249 .privileges(redfish::privileges::getPCIeSlots)
250 .methods(boost::beast::http::verb::get)(
251 std::bind_front(handlePCIeSlotCollectionGet, std::ref(app)));
252}
253
254} // namespace redfish