1 #pragma once 2 3 #include "async_resp.hpp" 4 #include "dbus_utility.hpp" 5 #include "error_messages.hpp" 6 #include "generated/enums/pcie_device.hpp" 7 #include "generated/enums/pcie_slots.hpp" 8 #include "http/utility.hpp" 9 10 #include <boost/system/error_code.hpp> 11 #include <boost/url/format.hpp> 12 #include <nlohmann/json.hpp> 13 14 #include <array> 15 #include <memory> 16 #include <optional> 17 #include <string> 18 #include <string_view> 19 20 namespace redfish 21 { 22 namespace pcie_util 23 { 24 25 /** 26 * @brief Populate the PCIe Device list from a GetSubTreePaths search of 27 * inventory 28 * 29 * @param[i,o] asyncResp Async response object 30 * @param[i] Name Key to store the list of PCIe devices in asyncResp 31 * 32 * @return void 33 */ 34 35 inline void 36 getPCIeDeviceList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 37 const std::string& name) 38 { 39 static constexpr std::array<std::string_view, 1> pcieDeviceInterface = { 40 "xyz.openbmc_project.Inventory.Item.PCIeDevice"}; 41 42 dbus::utility::getSubTreePaths( 43 "/xyz/openbmc_project/inventory", 0, pcieDeviceInterface, 44 [asyncResp, name](const boost::system::error_code& ec, 45 const dbus::utility::MapperGetSubTreePathsResponse& 46 pcieDevicePaths) { 47 if (ec) 48 { 49 BMCWEB_LOG_DEBUG << "no PCIe device paths found ec: " 50 << ec.message(); 51 // Not an error, system just doesn't have PCIe info 52 return; 53 } 54 nlohmann::json& pcieDeviceList = asyncResp->res.jsonValue[name]; 55 pcieDeviceList = nlohmann::json::array(); 56 for (const std::string& pcieDevicePath : pcieDevicePaths) 57 { 58 size_t devStart = pcieDevicePath.rfind('/'); 59 if (devStart == std::string::npos) 60 { 61 continue; 62 } 63 64 std::string devName = pcieDevicePath.substr(devStart + 1); 65 if (devName.empty()) 66 { 67 continue; 68 } 69 nlohmann::json::object_t pcieDevice; 70 pcieDevice["@odata.id"] = boost::urls::format( 71 "/redfish/v1/Systems/system/PCIeDevices/{}", devName); 72 pcieDeviceList.emplace_back(std::move(pcieDevice)); 73 } 74 asyncResp->res.jsonValue[name + "@odata.count"] = pcieDeviceList.size(); 75 }); 76 } 77 78 inline std::optional<pcie_slots::SlotTypes> 79 dbusSlotTypeToRf(const std::string& slotType) 80 { 81 if (slotType == 82 "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.FullLength") 83 { 84 return pcie_slots::SlotTypes::FullLength; 85 } 86 if (slotType == 87 "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.HalfLength") 88 { 89 return pcie_slots::SlotTypes::HalfLength; 90 } 91 if (slotType == 92 "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.LowProfile") 93 { 94 return pcie_slots::SlotTypes::LowProfile; 95 } 96 if (slotType == 97 "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.Mini") 98 { 99 return pcie_slots::SlotTypes::Mini; 100 } 101 if (slotType == "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.M_2") 102 { 103 return pcie_slots::SlotTypes::M2; 104 } 105 if (slotType == "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.OEM") 106 { 107 return pcie_slots::SlotTypes::OEM; 108 } 109 if (slotType == 110 "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.OCP3Small") 111 { 112 return pcie_slots::SlotTypes::OCP3Small; 113 } 114 if (slotType == 115 "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.OCP3Large") 116 { 117 return pcie_slots::SlotTypes::OCP3Large; 118 } 119 if (slotType == "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.U_2") 120 { 121 return pcie_slots::SlotTypes::U2; 122 } 123 if (slotType == 124 "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.Unknown") 125 { 126 return pcie_slots::SlotTypes::Invalid; 127 } 128 129 // Unspecified slotType should return an internal error. 130 return std::nullopt; 131 } 132 133 inline std::optional<pcie_device::PCIeTypes> 134 redfishPcieGenerationFromDbus(const std::string& generationInUse) 135 { 136 if (generationInUse == 137 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen1") 138 { 139 return pcie_device::PCIeTypes::Gen1; 140 } 141 if (generationInUse == 142 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen2") 143 { 144 return pcie_device::PCIeTypes::Gen2; 145 } 146 if (generationInUse == 147 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen3") 148 { 149 return pcie_device::PCIeTypes::Gen3; 150 } 151 if (generationInUse == 152 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen4") 153 { 154 return pcie_device::PCIeTypes::Gen4; 155 } 156 if (generationInUse == 157 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen5") 158 { 159 return pcie_device::PCIeTypes::Gen5; 160 } 161 if (generationInUse.empty() || 162 generationInUse == 163 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Unknown") 164 { 165 return pcie_device::PCIeTypes::Invalid; 166 } 167 168 // The value is not unknown or Gen1-5, need return an internal error. 169 return std::nullopt; 170 } 171 172 } // namespace pcie_util 173 } // namespace redfish 174