blob: 7246aea9e226356a8aba213776e29cd54e316c90 [file] [log] [blame]
Chicago Duan7691cc22021-01-25 19:52:35 +08001#pragma once
2
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08003#include "app.hpp"
George Liue99073f2022-12-09 11:06:16 +08004#include "dbus_utility.hpp"
Chicago Duan7691cc22021-01-25 19:52:35 +08005#include "error_messages.hpp"
Ed Tanous4ce2c1b2023-02-10 11:57:54 -08006#include "generated/enums/pcie_slots.hpp"
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -05007#include "query.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08008#include "registries/privilege_registry.hpp"
Chicago Duan7691cc22021-01-25 19:52:35 +08009#include "utility.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080010#include "utils/dbus_utils.hpp"
11#include "utils/json_utils.hpp"
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -050012#include "utils/pcie_util.hpp"
Chicago Duan7691cc22021-01-25 19:52:35 +080013
George Liue99073f2022-12-09 11:06:16 +080014#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070015#include <boost/url/format.hpp>
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020016#include <sdbusplus/asio/property.hpp>
17#include <sdbusplus/unpack_properties.hpp>
Chicago Duan7691cc22021-01-25 19:52:35 +080018
George Liue99073f2022-12-09 11:06:16 +080019#include <array>
20#include <string_view>
21
Chicago Duan7691cc22021-01-25 19:52:35 +080022namespace redfish
23{
24
Chicago Duan7691cc22021-01-25 19:52:35 +080025inline void
26 onPcieSlotGetAllDone(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -080027 const boost::system::error_code& ec,
Chicago Duan7691cc22021-01-25 19:52:35 +080028 const dbus::utility::DBusPropertiesMap& propertiesList)
29{
30 if (ec)
31 {
32 BMCWEB_LOG_ERROR << "Can't get PCIeSlot properties!";
33 messages::internalError(asyncResp->res);
34 return;
35 }
36
37 nlohmann::json& slots = asyncResp->res.jsonValue["Slots"];
38
39 nlohmann::json::array_t* slotsPtr =
40 slots.get_ptr<nlohmann::json::array_t*>();
41 if (slotsPtr == nullptr)
42 {
43 BMCWEB_LOG_ERROR << "Slots key isn't an array???";
44 messages::internalError(asyncResp->res);
45 return;
46 }
47
48 nlohmann::json::object_t slot;
49
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020050 const std::string* generation = nullptr;
51 const size_t* lanes = nullptr;
52 const std::string* slotType = nullptr;
53 const bool* hotPluggable = nullptr;
Chicago Duan7691cc22021-01-25 19:52:35 +080054
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020055 const bool success = sdbusplus::unpackPropertiesNoThrow(
56 dbus_utils::UnpackErrorPrinter(), propertiesList, "Generation",
57 generation, "Lanes", lanes, "SlotType", slotType, "HotPluggable",
58 hotPluggable);
59
60 if (!success)
61 {
62 messages::internalError(asyncResp->res);
63 return;
Chicago Duan7691cc22021-01-25 19:52:35 +080064 }
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020065
66 if (generation != nullptr)
67 {
Ed Tanous0ec8b832022-03-14 14:56:47 -070068 std::optional<pcie_device::PCIeTypes> pcieType =
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -050069 pcie_util::redfishPcieGenerationFromDbus(*generation);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020070 if (!pcieType)
71 {
72 messages::internalError(asyncResp->res);
73 return;
74 }
Lakshmi Yadlapatibbf372a2023-05-02 15:09:08 -050075 if (*pcieType != pcie_device::PCIeTypes::Invalid)
76 {
77 slot["PCIeType"] = *pcieType;
78 }
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020079 }
80
81 if (lanes != nullptr)
82 {
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020083 slot["Lanes"] = *lanes;
84 }
85
86 if (slotType != nullptr)
87 {
Lakshmi Yadlapatid87fdd92023-05-02 16:50:31 -050088 std::optional<pcie_slots::SlotTypes> redfishSlotType =
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -050089 pcie_util::dbusSlotTypeToRf(*slotType);
Lakshmi Yadlapatid87fdd92023-05-02 16:50:31 -050090 if (!redfishSlotType)
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020091 {
92 messages::internalError(asyncResp->res);
93 return;
94 }
Lakshmi Yadlapatid87fdd92023-05-02 16:50:31 -050095 if (*redfishSlotType != pcie_slots::SlotTypes::Invalid)
96 {
97 slot["SlotType"] = *redfishSlotType;
98 }
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020099 }
100
101 if (hotPluggable != nullptr)
102 {
103 slot["HotPluggable"] = *hotPluggable;
104 }
105
Chicago Duan7691cc22021-01-25 19:52:35 +0800106 slots.emplace_back(std::move(slot));
107}
108
109inline void onMapperAssociationDone(
110 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
111 const std::string& chassisID, const std::string& pcieSlotPath,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800112 const std::string& connectionName, const boost::system::error_code& ec,
George Liu6c3e9452023-03-03 13:55:29 +0800113 const dbus::utility::MapperEndPoints& pcieSlotChassis)
Chicago Duan7691cc22021-01-25 19:52:35 +0800114{
115 if (ec)
116 {
117 if (ec.value() == EBADR)
118 {
119 // This PCIeSlot have no chassis association.
120 return;
121 }
122 BMCWEB_LOG_ERROR << "DBUS response error";
123 messages::internalError(asyncResp->res);
124 return;
125 }
126
George Liu6c3e9452023-03-03 13:55:29 +0800127 if (pcieSlotChassis.size() != 1)
Chicago Duan7691cc22021-01-25 19:52:35 +0800128 {
129 BMCWEB_LOG_ERROR << "PCIe Slot association error! ";
130 messages::internalError(asyncResp->res);
131 return;
132 }
133
George Liu6c3e9452023-03-03 13:55:29 +0800134 sdbusplus::message::object_path path(pcieSlotChassis[0]);
Chicago Duan7691cc22021-01-25 19:52:35 +0800135 std::string chassisName = path.filename();
136 if (chassisName != chassisID)
137 {
138 // The pcie slot doesn't belong to the chassisID
139 return;
140 }
141
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200142 sdbusplus::asio::getAllProperties(
143 *crow::connections::systemBus, connectionName, pcieSlotPath,
144 "xyz.openbmc_project.Inventory.Item.PCIeSlot",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800145 [asyncResp](const boost::system::error_code& ec2,
Chicago Duan7691cc22021-01-25 19:52:35 +0800146 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous4ce2c1b2023-02-10 11:57:54 -0800147 onPcieSlotGetAllDone(asyncResp, ec2, propertiesList);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200148 });
Chicago Duan7691cc22021-01-25 19:52:35 +0800149}
150
151inline void
152 onMapperSubtreeDone(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
153 const std::string& chassisID,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800154 const boost::system::error_code& ec,
Chicago Duan7691cc22021-01-25 19:52:35 +0800155 const dbus::utility::MapperGetSubTreeResponse& subtree)
156{
157 if (ec)
158 {
159 BMCWEB_LOG_ERROR << "D-Bus response error on GetSubTree " << ec;
160 messages::internalError(asyncResp->res);
161 return;
162 }
163 if (subtree.empty())
164 {
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800165 messages::resourceNotFound(asyncResp->res, "Chassis", chassisID);
Chicago Duan7691cc22021-01-25 19:52:35 +0800166 return;
167 }
168
169 BMCWEB_LOG_DEBUG << "Get properties for PCIeSlots associated to chassis = "
170 << chassisID;
171
172 asyncResp->res.jsonValue["@odata.type"] = "#PCIeSlots.v1_4_1.PCIeSlots";
173 asyncResp->res.jsonValue["Name"] = "PCIe Slot Information";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700174 asyncResp->res.jsonValue["@odata.id"] =
175 boost::urls::format("/redfish/v1/Chassis/{}/PCIeSlots", chassisID);
Chicago Duan7691cc22021-01-25 19:52:35 +0800176 asyncResp->res.jsonValue["Id"] = "1";
177 asyncResp->res.jsonValue["Slots"] = nlohmann::json::array();
178
179 for (const auto& pathServicePair : subtree)
180 {
181 const std::string& pcieSlotPath = pathServicePair.first;
182 for (const auto& connectionInterfacePair : pathServicePair.second)
183 {
184 const std::string& connectionName = connectionInterfacePair.first;
185 sdbusplus::message::object_path pcieSlotAssociationPath(
186 pcieSlotPath);
187 pcieSlotAssociationPath /= "chassis";
188
189 // The association of this PCIeSlot is used to determine whether
190 // it belongs to this ChassisID
George Liu6c3e9452023-03-03 13:55:29 +0800191 dbus::utility::getAssociationEndPoints(
192 std::string{pcieSlotAssociationPath},
Chicago Duan7691cc22021-01-25 19:52:35 +0800193 [asyncResp, chassisID, pcieSlotPath, connectionName](
Ed Tanous4ce2c1b2023-02-10 11:57:54 -0800194 const boost::system::error_code& ec2,
George Liu6c3e9452023-03-03 13:55:29 +0800195 const dbus::utility::MapperEndPoints& endpoints) {
Chicago Duan7691cc22021-01-25 19:52:35 +0800196 onMapperAssociationDone(asyncResp, chassisID, pcieSlotPath,
Ed Tanous4ce2c1b2023-02-10 11:57:54 -0800197 connectionName, ec2, endpoints);
George Liu6c3e9452023-03-03 13:55:29 +0800198 });
Chicago Duan7691cc22021-01-25 19:52:35 +0800199 }
200 }
201}
202
203inline void handlePCIeSlotCollectionGet(
204 crow::App& app, const crow::Request& req,
205 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
206 const std::string& chassisID)
207{
Ed Tanous2aacf852022-06-17 08:07:54 -0700208 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Chicago Duan7691cc22021-01-25 19:52:35 +0800209 {
210 return;
211 }
212
George Liue99073f2022-12-09 11:06:16 +0800213 constexpr std::array<std::string_view, 1> interfaces = {
214 "xyz.openbmc_project.Inventory.Item.PCIeSlot"};
215 dbus::utility::getSubTree(
216 "/xyz/openbmc_project/inventory", 0, interfaces,
Chicago Duan7691cc22021-01-25 19:52:35 +0800217 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +0800218 chassisID](const boost::system::error_code& ec,
Chicago Duan7691cc22021-01-25 19:52:35 +0800219 const dbus::utility::MapperGetSubTreeResponse& subtree) {
220 onMapperSubtreeDone(asyncResp, chassisID, ec, subtree);
George Liue99073f2022-12-09 11:06:16 +0800221 });
Chicago Duan7691cc22021-01-25 19:52:35 +0800222}
223
224inline void requestRoutesPCIeSlots(App& app)
225{
226 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PCIeSlots/")
227 .privileges(redfish::privileges::getPCIeSlots)
228 .methods(boost::beast::http::verb::get)(
229 std::bind_front(handlePCIeSlotCollectionGet, std::ref(app)));
230}
231
232} // namespace redfish