blob: c95ab7ba7d2b8bbf37175a121910e1c80c009ef6 [file] [log] [blame]
Tom Joseph151d5332019-11-17 22:21:45 +05301#include "fru_parser.hpp"
2
George Liu6492f522020-06-16 10:34:05 +08003#include <nlohmann/json.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -06004#include <phosphor-logging/lg2.hpp>
George Liu6492f522020-06-16 10:34:05 +08005#include <xyz/openbmc_project/Common/error.hpp>
Alexander Hansend4a14d32025-11-18 11:43:06 +01006#include <xyz/openbmc_project/Inventory/Decorator/Asset/common.hpp>
7#include <xyz/openbmc_project/Inventory/Decorator/AssetTag/common.hpp>
8#include <xyz/openbmc_project/Inventory/Decorator/Revision/common.hpp>
9#include <xyz/openbmc_project/Inventory/Item/common.hpp>
George Liu6492f522020-06-16 10:34:05 +080010
Tom Joseph151d5332019-11-17 22:21:45 +053011#include <filesystem>
12#include <fstream>
Tom Joseph151d5332019-11-17 22:21:45 +053013
Riya Dixit49cfb132023-03-02 04:26:53 -060014PHOSPHOR_LOG2_USING;
15
Brad Bishop5079ac42021-08-19 18:35:06 -040016using namespace pldm::responder::dbus;
17
Tom Joseph151d5332019-11-17 22:21:45 +053018namespace pldm
19{
Tom Joseph151d5332019-11-17 22:21:45 +053020namespace responder
21{
Tom Joseph151d5332019-11-17 22:21:45 +053022namespace fru_parser
23{
Tom Joseph151d5332019-11-17 22:21:45 +053024using Json = nlohmann::json;
25using InternalFailure =
26 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Alexander Hansend4a14d32025-11-18 11:43:06 +010027using InventoryDecoratorAsset =
28 sdbusplus::common::xyz::openbmc_project::inventory::decorator::Asset;
29using InventoryDecoratorAssetTag =
30 sdbusplus::common::xyz::openbmc_project::inventory::decorator::AssetTag;
31using InventoryDecoratorRevision =
32 sdbusplus::common::xyz::openbmc_project::inventory::decorator::Revision;
33using InventoryItem = sdbusplus::common::xyz::openbmc_project::inventory::Item;
Tom Joseph151d5332019-11-17 22:21:45 +053034
35const Json emptyJson{};
36const std::vector<Json> emptyJsonList{};
Tom Joseph151d5332019-11-17 22:21:45 +053037
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053038FruParser::FruParser(const std::string& dirPath,
39 const fs::path& fruMasterJsonPath)
Tom Joseph151d5332019-11-17 22:21:45 +053040{
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053041 if (fs::exists(fruMasterJsonPath))
42 {
43 setupDefaultDBusLookup(fruMasterJsonPath);
44 }
Deepak Kodihallida079602020-08-05 03:23:03 -050045 setupDefaultFruRecordMap();
46
Tom Joseph151d5332019-11-17 22:21:45 +053047 fs::path dir(dirPath);
Deepak Kodihallida079602020-08-05 03:23:03 -050048 if (fs::exists(dir) && !fs::is_empty(dir))
Tom Joseph151d5332019-11-17 22:21:45 +053049 {
Deepak Kodihallida079602020-08-05 03:23:03 -050050 setupFruRecordMap(dirPath);
Tom Joseph151d5332019-11-17 22:21:45 +053051 }
Tom Joseph151d5332019-11-17 22:21:45 +053052}
53
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053054void FruParser::setupDefaultDBusLookup(const fs::path& masterJsonPath)
John Wang55732c22020-05-14 10:33:00 +080055{
56 constexpr auto service = "xyz.openbmc_project.Inventory.Manager";
57 constexpr auto rootPath = "/xyz/openbmc_project/inventory";
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053058 std::ifstream jsonFile(masterJsonPath);
59 auto data = Json::parse(jsonFile, nullptr, false);
60 if (data.is_discarded())
61 {
Riya Dixit89644442024-03-31 05:39:59 -050062 error("Failed to parse FRU Dbus Lookup Map config file '{PATH}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050063 "PATH", masterJsonPath);
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053064 std::abort();
65 }
66 std::map<Interface, EntityType> defIntfToEntityType;
67 auto dbusMap = data.value("FruDBusLookupMap", emptyJson);
68 for (const auto& element : dbusMap.items())
69
70 {
71 try
72 {
73 defIntfToEntityType[static_cast<Interface>(element.key())] =
74 static_cast<EntityType>(element.value());
75 }
76 catch (const std::exception& e)
77 {
Riya Dixit89644442024-03-31 05:39:59 -050078 error("Failure in FRU dbus lookup map format, error - {ERROR}",
79 "ERROR", e);
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053080 throw InternalFailure();
81 }
82 }
John Wang55732c22020-05-14 10:33:00 +080083
84 Interfaces interfaces{};
85 for (auto [intf, entityType] : defIntfToEntityType)
86 {
87 intfToEntityType[intf] = entityType;
88 interfaces.emplace(intf);
89 }
90
91 lookupInfo.emplace(service, rootPath, std::move(interfaces));
92}
93
John Wang55732c22020-05-14 10:33:00 +080094void FruParser::setupDefaultFruRecordMap()
95{
96 const FruRecordInfo generalRecordInfo = {
97 1, // generalRecordType
98 1, // encodingTypeASCII
99 {
100 // DSP0257 Table 5 General FRU Record Field Type Definitions
Alexander Hansend4a14d32025-11-18 11:43:06 +0100101 {InventoryDecoratorAsset::interface,
102 InventoryDecoratorAsset::property_names::model, "string", 2},
103 {InventoryDecoratorAsset::interface,
104 InventoryDecoratorAsset::property_names::part_number, "string", 3},
105 {InventoryDecoratorAsset::interface,
106 InventoryDecoratorAsset::property_names::serial_number, "string",
107 4},
108 {InventoryDecoratorAsset::interface,
109 InventoryDecoratorAsset::property_names::manufacturer, "string",
110 5},
111 {InventoryItem::interface,
112 InventoryItem::property_names::pretty_name, "string", 8},
113 {InventoryDecoratorAssetTag::interface,
114 InventoryDecoratorAssetTag::property_names::asset_tag, "string",
115 11},
116 {InventoryDecoratorRevision::interface,
117 InventoryDecoratorRevision::property_names::version, "string", 10},
John Wang55732c22020-05-14 10:33:00 +0800118 }};
119
120 for (auto [intf, entityType] : intfToEntityType)
121 {
122 recordMap[intf] = {generalRecordInfo};
123 }
124}
125
Tom Joseph151d5332019-11-17 22:21:45 +0530126void FruParser::setupFruRecordMap(const std::string& dirPath)
127{
128 for (auto& file : fs::directory_iterator(dirPath))
129 {
130 auto fileName = file.path().filename().string();
Tom Joseph151d5332019-11-17 22:21:45 +0530131 std::ifstream jsonFile(file.path());
132 auto data = Json::parse(jsonFile, nullptr, false);
133 if (data.is_discarded())
134 {
Riya Dixit89644442024-03-31 05:39:59 -0500135 error("Failed to parse FRU config file at '{PATH}'", "PATH",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500136 file.path());
Tom Joseph151d5332019-11-17 22:21:45 +0530137 throw InternalFailure();
138 }
139
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500140 try
Tom Joseph151d5332019-11-17 22:21:45 +0530141 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500142 auto record = data.value("record_details", emptyJson);
143 auto recordType =
144 static_cast<uint8_t>(record.value("fru_record_type", 0));
145 auto encType =
146 static_cast<uint8_t>(record.value("fru_encoding_type", 0));
147 auto dbusIntfName = record.value("dbus_interface_name", "");
148 auto entries = data.value("fru_fields", emptyJsonList);
149 std::vector<FieldInfo> fieldInfo;
150
151 for (const auto& entry : entries)
152 {
153 auto fieldType =
154 static_cast<uint8_t>(entry.value("fru_field_type", 0));
155 auto dbus = entry.value("dbus", emptyJson);
156 auto interface = dbus.value("interface", "");
157 auto property = dbus.value("property_name", "");
158 auto propType = dbus.value("property_type", "");
159 fieldInfo.emplace_back(
160 std::make_tuple(std::move(interface), std::move(property),
161 std::move(propType), std::move(fieldType)));
162 }
163
164 FruRecordInfo fruInfo;
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400165 fruInfo =
166 std::make_tuple(recordType, encType, std::move(fieldInfo));
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500167
168 auto search = recordMap.find(dbusIntfName);
169
170 // PLDM FRU can have multiple records for the same FRU like General
171 // FRU record and multiple OEM FRU records. If the FRU item
172 // interface name is already in the map, that indicates a record
173 // info is already added for the FRU, so append the new record info
174 // to the same data.
175 if (search != recordMap.end())
176 {
177 search->second.emplace_back(std::move(fruInfo));
178 }
179 else
180 {
181 FruRecordInfos recordInfos{fruInfo};
182 recordMap.emplace(dbusIntfName, recordInfos);
183 }
Tom Joseph151d5332019-11-17 22:21:45 +0530184 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500185 catch (const std::exception&)
Tom Joseph151d5332019-11-17 22:21:45 +0530186 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500187 continue;
Tom Joseph151d5332019-11-17 22:21:45 +0530188 }
189 }
190}
191
192} // namespace fru_parser
193
194} // namespace responder
195
196} // namespace pldm