Update to PCIeDevices 1.4 and add PCIeFunctionCollection support
v1.4 of PCIe Devices changed from an array of Links to PCIeFunctions
to a PCIeFunctionCollection. This change adds support for the
PCIeFunctionCollection and references it from the PCIeDevices.
Tested:
Passed the Redfish Service Validator.
Change-Id: I76f0265c588b52bd02a35bf669ae6edacfb6c2a4
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 5895ee1..bf0f51f 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -139,6 +139,7 @@
nodes.emplace_back(
std::make_unique<TrustStoreCertificateCollection>(app));
nodes.emplace_back(std::make_unique<TrustStoreCertificate>(app));
+ nodes.emplace_back(std::make_unique<SystemPCIeFunctionCollection>(app));
nodes.emplace_back(std::make_unique<SystemPCIeFunction>(app));
nodes.emplace_back(std::make_unique<SystemPCIeDevice>(app));
diff --git a/redfish-core/lib/pcie.hpp b/redfish-core/lib/pcie.hpp
index 5b4f5c5..64ccdb2 100644
--- a/redfish-core/lib/pcie.hpp
+++ b/redfish-core/lib/pcie.hpp
@@ -123,9 +123,9 @@
}
asyncResp->res.jsonValue = {
- {"@odata.type", "#PCIeDevice.v1_2_0.PCIeDevice"},
+ {"@odata.type", "#PCIeDevice.v1_4_0.PCIeDevice"},
{"@odata.context",
- "/redfish/v1/$metadata#PCIeDevice.v1_2_0.PCIeDevice"},
+ "/redfish/v1/$metadata#PCIeDevice.v1_4_0.PCIeDevice"},
{"@odata.id",
"/redfish/v1/Systems/system/PCIeDevices/" + device},
{"Name", "PCIe Device"},
@@ -147,8 +147,86 @@
asyncResp->res.jsonValue["DeviceType"] = *property;
}
+ asyncResp->res.jsonValue["PCIeFunctions"] = {
+ {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" +
+ device + "/PCIeFunctions"}};
+ };
+ std::string escapedPath = std::string(pciePath) + "/" + device;
+ dbus::utility::escapePathForDbus(escapedPath);
+ crow::connections::systemBus->async_method_call(
+ std::move(getPCIeDeviceCallback), pcieService, escapedPath,
+ "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface);
+ }
+};
+
+class SystemPCIeFunctionCollection : public Node
+{
+ public:
+ template <typename CrowApp>
+ SystemPCIeFunctionCollection(CrowApp &app) :
+ Node(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/",
+ std::string())
+ {
+ entityPrivileges = {
+ {boost::beast::http::verb::get, {{"Login"}}},
+ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+ }
+
+ private:
+ /**
+ * Functions triggers appropriate requests on DBus
+ */
+ void doGet(crow::Response &res, const crow::Request &req,
+ const std::vector<std::string> ¶ms) override
+ {
+ std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
+ if (params.size() != 1)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ const std::string &device = params[0];
+ asyncResp->res.jsonValue = {
+ {"@odata.type", "#PCIeFunctionCollection.PCIeFunctionCollection"},
+ {"@odata.context",
+ "/redfish/v1/"
+ "$metadata#PCIeFunctionCollection.PCIeFunctionCollection"},
+ {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + device +
+ "/PCIeFunctions"},
+ {"Name", "PCIe Function Collection"},
+ {"Description",
+ "Collection of PCIe Functions for PCIe Device " + device}};
+
+ auto getPCIeDeviceCallback =
+ [asyncResp,
+ device](const boost::system::error_code ec,
+ boost::container::flat_map<
+ std::string, sdbusplus::message::variant<std::string>>
+ &pcieDevProperties) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG
+ << "failed to get PCIe Device properties ec: "
+ << ec.value() << ": " << ec.message();
+ if (ec.value() ==
+ boost::system::linux_error::bad_request_descriptor)
+ {
+ messages::resourceNotFound(asyncResp->res, "PCIeDevice",
+ device);
+ }
+ else
+ {
+ messages::internalError(asyncResp->res);
+ }
+ return;
+ }
+
nlohmann::json &pcieFunctionList =
- asyncResp->res.jsonValue["Links"]["PCIeFunctions"];
+ asyncResp->res.jsonValue["Members"];
pcieFunctionList = nlohmann::json::array();
static constexpr const int maxPciFunctionNum = 8;
for (int functionNum = 0; functionNum < maxPciFunctionNum;
@@ -157,10 +235,10 @@
// Check if this function exists by looking for a device ID
std::string devIDProperty =
"Function" + std::to_string(functionNum) + "DeviceId";
- if (std::string *property =
- sdbusplus::message::variant_ns::get_if<std::string>(
- &pcieDevProperties[devIDProperty]);
- property && !property->empty())
+ std::string *property =
+ sdbusplus::message::variant_ns::get_if<std::string>(
+ &pcieDevProperties[devIDProperty]);
+ if (property && !property->empty())
{
pcieFunctionList.push_back(
{{"@odata.id",
@@ -169,7 +247,7 @@
std::to_string(functionNum)}});
}
}
- asyncResp->res.jsonValue["Links"]["PCIeFunctions@odata.count"] =
+ asyncResp->res.jsonValue["PCIeFunctions@odata.count"] =
pcieFunctionList.size();
};
std::string escapedPath = std::string(pciePath) + "/" + device;