blob: 781227a8f2c60d7e868050a1dbcd0b1456483e95 [file] [log] [blame]
Deepak Kodihalli70e8db02019-10-21 00:59:46 -05001#pragma once
2
Deepak Kodihalli70e8db02019-10-21 00:59:46 -05003#include "fru_parser.hpp"
Pavithra Barithayaa410c652021-07-22 01:32:47 -05004#include "libpldmresponder/pdr_utils.hpp"
5#include "oem_handler.hpp"
Deepak Kodihalli1521f6d2020-06-16 08:51:02 -05006#include "pldmd/handler.hpp"
Deepak Kodihalli70e8db02019-10-21 00:59:46 -05007
George Liuc453e162022-12-21 17:16:23 +08008#include <libpldm/fru.h>
9#include <libpldm/pdr.h>
10
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050011#include <sdbusplus/message.hpp>
George Liu6492f522020-06-16 10:34:05 +080012
13#include <map>
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050014#include <string>
15#include <variant>
16#include <vector>
17
Pavithra Barithayacee5ecc2025-09-17 16:31:31 +053018using namespace pldm::utils;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050019namespace pldm
20{
21
22namespace responder
23{
24
25namespace dbus
26{
27
Unive Tienc40d4a62025-03-12 11:36:07 +080028using Value =
29 std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
30 uint64_t, double, std::string, std::vector<uint8_t>,
31 std::vector<uint64_t>, std::vector<std::string>>;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050032using PropertyMap = std::map<Property, Value>;
33using InterfaceMap = std::map<Interface, PropertyMap>;
34using ObjectValueTree = std::map<sdbusplus::message::object_path, InterfaceMap>;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -050035using ObjectPath = std::string;
George Liuc4ea6a92020-07-14 15:48:44 +080036using AssociatedEntityMap = std::map<ObjectPath, pldm_entity>;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050037
38} // namespace dbus
39
40/** @class FruImpl
41 *
42 * @brief Builds the PLDM FRU table containing the FRU records
43 */
44class FruImpl
45{
46 public:
47 /* @brief Header size for FRU record, it includes the FRU record set
48 * identifier, FRU record type, Number of FRU fields, Encoding type
49 * of FRU fields
50 */
51 static constexpr size_t recHeaderSize =
52 sizeof(struct pldm_fru_record_data_format) -
53 sizeof(struct pldm_fru_record_tlv);
54
Tom Joseph33e9c7e2020-06-11 22:09:52 +053055 /** @brief Constructor for FruImpl, the configPath is consumed to build the
56 * FruParser object.
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050057 *
58 * @param[in] configPath - path to the directory containing config files
Tom Joseph33e9c7e2020-06-11 22:09:52 +053059 * for PLDM FRU
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053060 * @param[in] fruMasterJsonPath - path to the file containing the FRU D-Bus
61 * Lookup Map
Tom Joseph33e9c7e2020-06-11 22:09:52 +053062 * @param[in] pdrRepo - opaque pointer to PDR repository
63 * @param[in] entityTree - opaque pointer to the entity association tree
Sampa Misrac073a202021-05-08 10:56:05 -050064 * @param[in] bmcEntityTree - opaque pointer to bmc's entity association
65 * tree
Pavithra Barithayaa410c652021-07-22 01:32:47 -050066 * @param[in] oemFruHandler - OEM fru handler
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050067 */
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053068 FruImpl(const std::string& configPath,
69 const std::filesystem::path& fruMasterJsonPath, pldm_pdr* pdrRepo,
Sampa Misrac073a202021-05-08 10:56:05 -050070 pldm_entity_association_tree* entityTree,
George Liua881c172021-06-21 18:28:11 +080071 pldm_entity_association_tree* bmcEntityTree) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040072 parser(configPath, fruMasterJsonPath), pdrRepo(pdrRepo),
Pavithra Barithayacee5ecc2025-09-17 16:31:31 +053073 entityTree(entityTree), bmcEntityTree(bmcEntityTree),
74 oemUtilsHandler(nullptr)
Tom Joseph33e9c7e2020-06-11 22:09:52 +053075 {}
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050076
Pavithra Barithaya9e6631e2024-01-22 00:46:32 -060077 /** @brief Total length of the FRU table in bytes, this includes the pad
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050078 * bytes and the checksum.
79 *
80 * @return size of the FRU table
81 */
82 uint32_t size() const
83 {
Pavithra Barithaya9e6631e2024-01-22 00:46:32 -060084 return table.size();
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050085 }
86
87 /** @brief The checksum of the contents of the FRU table
88 *
89 * @return checksum
90 */
91 uint32_t checkSum() const
92 {
93 return checksum;
94 }
95
96 /** @brief Number of record set identifiers in the FRU tables
97 *
98 * @return number of record set identifiers
99 */
100 uint16_t numRSI() const
101 {
102 return rsi;
103 }
104
105 /** @brief The number of FRU records in the table
106 *
107 * @return number of FRU records
108 */
109 uint16_t numRecords() const
110 {
111 return numRecs;
112 }
113
114 /** @brief Get the FRU table
115 *
116 * @param[out] - Populate response with the FRU table
117 */
118 void getFRUTable(Response& response);
119
Pavithra Barithaya9e6631e2024-01-22 00:46:32 -0600120 /** @brief Get the Fru Table MetaData
121 *
122 */
123 void getFRURecordTableMetadata();
124
John Wang9e82ad12020-06-12 10:53:32 +0800125 /** @brief Get FRU Record Table By Option
126 * @param[out] response - Populate response with the FRU table got by
127 * options
128 * @param[in] fruTableHandle - The fru table handle
129 * @param[in] recordSetIdentifer - The record set identifier
130 * @param[in] recordType - The record type
131 * @param[in] fieldType - The field type
132 */
133 int getFRURecordByOption(Response& response, uint16_t fruTableHandle,
134 uint16_t recordSetIdentifer, uint8_t recordType,
135 uint8_t fieldType);
136
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530137 /** @brief FRU table is built by processing the D-Bus inventory namespace
138 * based on the config files for FRU. The table is populated based
139 * on the isBuilt flag.
140 */
141 void buildFRUTable();
142
George Liuc4ea6a92020-07-14 15:48:44 +0800143 /** @brief Get std::map associated with the entity
144 * key: object path
145 * value: pldm_entity
146 *
147 * @return std::map<ObjectPath, pldm_entity>
148 */
149 inline const pldm::responder::dbus::AssociatedEntityMap&
150 getAssociateEntityMap() const
151 {
152 return associatedEntityMap;
153 }
154
Pavithra Barithayacee5ecc2025-09-17 16:31:31 +0530155 /* @brief Method to set the oem utils handler in FRU handler class
156 *
157 * @param[in] handler - oem utils handler
158 */
159 inline void setOemUtilsHandler(pldm::responder::oem_utils::Handler* handler)
160 {
161 oemUtilsHandler = handler;
162 }
163
George Liu5bfb0dc2021-05-01 14:28:41 +0800164 /** @brief Get pldm entity by the object path
165 *
166 * @param[in] intfMaps - D-Bus interfaces and the associated property
167 * values for the FRU
168 *
169 * @return pldm_entity
170 */
Patrick Williams366507c2025-02-03 14:28:01 -0500171 std::optional<pldm_entity> getEntityByObjectPath(
172 const dbus::InterfaceMap& intfMaps);
George Liu5bfb0dc2021-05-01 14:28:41 +0800173
174 /** @brief Update pldm entity to association tree
175 *
176 * @param[in] objects - std::map The object value tree
177 * @param[in] path - Object path
178 *
179 * Ex: Input path =
180 * "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
181 *
182 * Get the parent class in turn and store it in a temporary vector
183 *
184 * Output tmpObjPaths = {
185 * "/xyz/openbmc_project/inventory/system",
186 * "/xyz/openbmc_project/inventory/system/chassis/",
187 * "/xyz/openbmc_project/inventory/system/chassis/motherboard",
188 * "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"}
189 *
190 */
191 void updateAssociationTree(const dbus::ObjectValueTree& objects,
192 const std::string& path);
193
Pavithra Barithaya47180ac2020-10-28 02:12:05 -0500194 /* @brief Method to populate the firmware version ID
195 *
196 * @return firmware version ID
197 */
198 std::string populatefwVersion();
199
Pavithra Barithaya9e6631e2024-01-22 00:46:32 -0600200 /* @brief Method to resize the table
201 *
202 * @return resized table
203 */
204 std::vector<uint8_t> tableResize();
205
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500206 /* @brief set FRU Record Table
207 *
208 * @param[in] fruData - the data of the fru
209 *
210 * @return PLDM completion code
211 */
212 int setFRUTable(const std::vector<uint8_t>& fruData);
213
George Liua881c172021-06-21 18:28:11 +0800214 /* @brief Method to set the oem platform handler in fru handler class
215 *
216 * @param[in] handler - oem fru handler
217 */
218 inline void setOemFruHandler(pldm::responder::oem_fru::Handler* handler)
219 {
220 oemFruHandler = handler;
221 }
222
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500223 private:
224 uint16_t nextRSI()
225 {
226 return ++rsi;
227 }
228
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600229 uint32_t nextRecordHandle()
230 {
231 return ++rh;
232 }
233
234 uint32_t rh = 0;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500235 uint16_t rsi = 0;
236 uint16_t numRecs = 0;
237 uint8_t padBytes = 0;
238 std::vector<uint8_t> table;
239 uint32_t checksum = 0;
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530240 bool isBuilt = false;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500241
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530242 fru_parser::FruParser parser;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500243 pldm_pdr* pdrRepo;
244 pldm_entity_association_tree* entityTree;
Sampa Misrac073a202021-05-08 10:56:05 -0500245 pldm_entity_association_tree* bmcEntityTree;
George Liua881c172021-06-21 18:28:11 +0800246 pldm::responder::oem_fru::Handler* oemFruHandler = nullptr;
Riya Dixit754041d2024-02-20 06:15:49 -0600247 dbus::ObjectValueTree objects;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500248
249 std::map<dbus::ObjectPath, pldm_entity_node*> objToEntityNode{};
Pavithra Barithayacee5ecc2025-09-17 16:31:31 +0530250 /** @OEM Utils handler */
251 pldm::responder::oem_utils::Handler* oemUtilsHandler;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500252
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500253 /** @brief populateRecord builds the FRU records for an instance of FRU and
254 * updates the FRU table with the FRU records.
255 *
256 * @param[in] interfaces - D-Bus interfaces and the associated property
257 * values for the FRU
258 * @param[in] recordInfos - FRU record info to build the FRU records
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500259 * @param[in/out] entity - PLDM entity corresponding to FRU instance
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500260 */
George Liuc4ea6a92020-07-14 15:48:44 +0800261 void populateRecords(const dbus::InterfaceMap& interfaces,
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500262 const fru_parser::FruRecordInfos& recordInfos,
263 const pldm_entity& entity);
George Liuc4ea6a92020-07-14 15:48:44 +0800264
Pavithra Barithaya129dab12025-04-24 16:13:03 +0530265 /** @brief Deletes a FRU record from record set table.
266 * @param[in] rsi - the FRU Record Set Identifier
267 *
268 * @return
269 */
270 void deleteFRURecord(uint16_t rsi);
271
Pavithra Barithayacee5ecc2025-09-17 16:31:31 +0530272 /** @brief Add hotplug record that was modified or added to the PDR entry
273 * HotPlug is a feature where a FRU can be removed or added when
274 * the system is running, without needing it to power off.
275 *
276 * @param[in] pdrEntry - PDR record structure in PDR repository
277 *
278 * @return record handle of added or modified hotplug record
279 */
280 uint32_t addHotPlugRecord(pldm::responder::pdr_utils::PdrEntry pdrEntry);
281
George Liuc4ea6a92020-07-14 15:48:44 +0800282 /** @brief Associate sensor/effecter to FRU entity
283 */
284 dbus::AssociatedEntityMap associatedEntityMap;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500285};
286
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500287namespace fru
288{
289
290class Handler : public CmdHandler
291{
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500292 public:
Manojkiran Eda03b01ca2021-06-29 08:55:09 +0530293 Handler(const std::string& configPath,
294 const std::filesystem::path& fruMasterJsonPath, pldm_pdr* pdrRepo,
Sampa Misrac073a202021-05-08 10:56:05 -0500295 pldm_entity_association_tree* entityTree,
George Liua881c172021-06-21 18:28:11 +0800296 pldm_entity_association_tree* bmcEntityTree) :
297 impl(configPath, fruMasterJsonPath, pdrRepo, entityTree, bmcEntityTree)
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500298 {
Delphine CC Chiud2e48992023-12-05 16:29:51 +0800299 handlers.emplace(
300 PLDM_GET_FRU_RECORD_TABLE_METADATA,
301 [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400302 return this->getFRURecordTableMetadata(request, payloadLength);
303 });
Delphine CC Chiud2e48992023-12-05 16:29:51 +0800304 handlers.emplace(
305 PLDM_GET_FRU_RECORD_TABLE,
306 [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400307 return this->getFRURecordTable(request, payloadLength);
308 });
Delphine CC Chiud2e48992023-12-05 16:29:51 +0800309 handlers.emplace(
310 PLDM_GET_FRU_RECORD_BY_OPTION,
311 [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400312 return this->getFRURecordByOption(request, payloadLength);
313 });
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500314 handlers.emplace(
315 PLDM_SET_FRU_RECORD_TABLE,
316 [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400317 return this->setFRURecordTable(request, payloadLength);
318 });
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500319 }
320
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500321 /** @brief Handler for Get FRURecordTableMetadata
322 *
323 * @param[in] request - Request message payload
324 * @param[in] payloadLength - Request payload length
325 *
326 * @return PLDM response message
327 */
328 Response getFRURecordTableMetadata(const pldm_msg* request,
329 size_t payloadLength);
330
331 /** @brief Handler for GetFRURecordTable
332 *
333 * @param[in] request - Request message payload
334 * @param[in] payloadLength - Request payload length
335 *
336 * @return PLDM response message
337 */
338 Response getFRURecordTable(const pldm_msg* request, size_t payloadLength);
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500339
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530340 /** @brief Build FRU table is bnot already built
341 *
342 */
343 void buildFRUTable()
344 {
345 impl.buildFRUTable();
346 }
347
George Liuc4ea6a92020-07-14 15:48:44 +0800348 /** @brief Get std::map associated with the entity
349 * key: object path
350 * value: pldm_entity
351 *
352 * @return std::map<ObjectPath, pldm_entity>
353 */
Patrick Williams366507c2025-02-03 14:28:01 -0500354 const pldm::responder::dbus::AssociatedEntityMap& getAssociateEntityMap()
355 const
George Liuc4ea6a92020-07-14 15:48:44 +0800356 {
357 return impl.getAssociateEntityMap();
358 }
359
Pavithra Barithayacee5ecc2025-09-17 16:31:31 +0530360 /* @brief Method to set the oem utils handler in host pdr handler class
361 *
362 * @param[in] handler - oem utils handler
363 */
364 void setOemUtilsHandler(pldm::responder::oem_utils::Handler* handler)
365 {
366 return impl.setOemUtilsHandler(handler);
367 }
368
John Wang9e82ad12020-06-12 10:53:32 +0800369 /** @brief Handler for GetFRURecordByOption
370 *
371 * @param[in] request - Request message payload
372 * @param[in] payloadLength - Request payload length
373 *
374 * @return PLDM response message
375 */
376 Response getFRURecordByOption(const pldm_msg* request,
377 size_t payloadLength);
378
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500379 /** @brief Handler for SetFRURecordTable
380 *
381 * @param[in] request - Request message
382 * @param[in] payloadLength - Request payload length
383 *
384 * @return PLDM response message
385 */
386 Response setFRURecordTable(const pldm_msg* request, size_t payloadLength);
387
George Liua881c172021-06-21 18:28:11 +0800388 /* @brief Method to set the oem platform handler in fru handler class
389 *
390 * @param[in] handler - oem fru handler
391 */
392 void setOemFruHandler(pldm::responder::oem_fru::Handler* handler)
393 {
394 impl.setOemFruHandler(handler);
395 }
396
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500397 using Table = std::vector<uint8_t>;
398
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500399 private:
400 FruImpl impl;
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500401};
402
403} // namespace fru
404
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500405} // namespace responder
406
407} // namespace pldm