blob: 20bc509ddb093e8f0250d8a9aa335b5776d3aee0 [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
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050018namespace pldm
19{
20
21namespace responder
22{
23
24namespace dbus
25{
26
27using Value =
28 std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
29 uint64_t, double, std::string, std::vector<uint8_t>>;
30using PropertyMap = std::map<Property, Value>;
31using InterfaceMap = std::map<Interface, PropertyMap>;
32using ObjectValueTree = std::map<sdbusplus::message::object_path, InterfaceMap>;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -050033using ObjectPath = std::string;
George Liuc4ea6a92020-07-14 15:48:44 +080034using AssociatedEntityMap = std::map<ObjectPath, pldm_entity>;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050035
36} // namespace dbus
37
38/** @class FruImpl
39 *
40 * @brief Builds the PLDM FRU table containing the FRU records
41 */
42class FruImpl
43{
44 public:
45 /* @brief Header size for FRU record, it includes the FRU record set
46 * identifier, FRU record type, Number of FRU fields, Encoding type
47 * of FRU fields
48 */
49 static constexpr size_t recHeaderSize =
50 sizeof(struct pldm_fru_record_data_format) -
51 sizeof(struct pldm_fru_record_tlv);
52
Tom Joseph33e9c7e2020-06-11 22:09:52 +053053 /** @brief Constructor for FruImpl, the configPath is consumed to build the
54 * FruParser object.
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050055 *
56 * @param[in] configPath - path to the directory containing config files
Tom Joseph33e9c7e2020-06-11 22:09:52 +053057 * for PLDM FRU
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053058 * @param[in] fruMasterJsonPath - path to the file containing the FRU D-Bus
59 * Lookup Map
Tom Joseph33e9c7e2020-06-11 22:09:52 +053060 * @param[in] pdrRepo - opaque pointer to PDR repository
61 * @param[in] entityTree - opaque pointer to the entity association tree
Sampa Misrac073a202021-05-08 10:56:05 -050062 * @param[in] bmcEntityTree - opaque pointer to bmc's entity association
63 * tree
Pavithra Barithayaa410c652021-07-22 01:32:47 -050064 * @param[in] oemFruHandler - OEM fru handler
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050065 */
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053066 FruImpl(const std::string& configPath,
67 const std::filesystem::path& fruMasterJsonPath, pldm_pdr* pdrRepo,
Sampa Misrac073a202021-05-08 10:56:05 -050068 pldm_entity_association_tree* entityTree,
Pavithra Barithayaa410c652021-07-22 01:32:47 -050069 pldm_entity_association_tree* bmcEntityTree,
70 pldm::responder::oem_fru::Handler* oemFruHandler) :
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053071 parser(configPath, fruMasterJsonPath),
Pavithra Barithayaa410c652021-07-22 01:32:47 -050072 pdrRepo(pdrRepo), entityTree(entityTree), bmcEntityTree(bmcEntityTree),
73 oemFruHandler(oemFruHandler)
Tom Joseph33e9c7e2020-06-11 22:09:52 +053074 {}
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050075
Pavithra Barithaya9e6631e2024-01-22 00:46:32 -060076 /** @brief Total length of the FRU table in bytes, this includes the pad
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050077 * bytes and the checksum.
78 *
79 * @return size of the FRU table
80 */
81 uint32_t size() const
82 {
Pavithra Barithaya9e6631e2024-01-22 00:46:32 -060083 return table.size();
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050084 }
85
86 /** @brief The checksum of the contents of the FRU table
87 *
88 * @return checksum
89 */
90 uint32_t checkSum() const
91 {
92 return checksum;
93 }
94
95 /** @brief Number of record set identifiers in the FRU tables
96 *
97 * @return number of record set identifiers
98 */
99 uint16_t numRSI() const
100 {
101 return rsi;
102 }
103
104 /** @brief The number of FRU records in the table
105 *
106 * @return number of FRU records
107 */
108 uint16_t numRecords() const
109 {
110 return numRecs;
111 }
112
113 /** @brief Get the FRU table
114 *
115 * @param[out] - Populate response with the FRU table
116 */
117 void getFRUTable(Response& response);
118
Pavithra Barithaya9e6631e2024-01-22 00:46:32 -0600119 /** @brief Get the Fru Table MetaData
120 *
121 */
122 void getFRURecordTableMetadata();
123
John Wang9e82ad12020-06-12 10:53:32 +0800124 /** @brief Get FRU Record Table By Option
125 * @param[out] response - Populate response with the FRU table got by
126 * options
127 * @param[in] fruTableHandle - The fru table handle
128 * @param[in] recordSetIdentifer - The record set identifier
129 * @param[in] recordType - The record type
130 * @param[in] fieldType - The field type
131 */
132 int getFRURecordByOption(Response& response, uint16_t fruTableHandle,
133 uint16_t recordSetIdentifer, uint8_t recordType,
134 uint8_t fieldType);
135
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530136 /** @brief FRU table is built by processing the D-Bus inventory namespace
137 * based on the config files for FRU. The table is populated based
138 * on the isBuilt flag.
139 */
140 void buildFRUTable();
141
George Liuc4ea6a92020-07-14 15:48:44 +0800142 /** @brief Get std::map associated with the entity
143 * key: object path
144 * value: pldm_entity
145 *
146 * @return std::map<ObjectPath, pldm_entity>
147 */
148 inline const pldm::responder::dbus::AssociatedEntityMap&
149 getAssociateEntityMap() const
150 {
151 return associatedEntityMap;
152 }
153
George Liu5bfb0dc2021-05-01 14:28:41 +0800154 /** @brief Get pldm entity by the object path
155 *
156 * @param[in] intfMaps - D-Bus interfaces and the associated property
157 * values for the FRU
158 *
159 * @return pldm_entity
160 */
161 std::optional<pldm_entity>
162 getEntityByObjectPath(const dbus::InterfaceMap& intfMaps);
163
164 /** @brief Update pldm entity to association tree
165 *
166 * @param[in] objects - std::map The object value tree
167 * @param[in] path - Object path
168 *
169 * Ex: Input path =
170 * "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
171 *
172 * Get the parent class in turn and store it in a temporary vector
173 *
174 * Output tmpObjPaths = {
175 * "/xyz/openbmc_project/inventory/system",
176 * "/xyz/openbmc_project/inventory/system/chassis/",
177 * "/xyz/openbmc_project/inventory/system/chassis/motherboard",
178 * "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"}
179 *
180 */
181 void updateAssociationTree(const dbus::ObjectValueTree& objects,
182 const std::string& path);
183
Pavithra Barithaya47180ac2020-10-28 02:12:05 -0500184 /* @brief Method to populate the firmware version ID
185 *
186 * @return firmware version ID
187 */
188 std::string populatefwVersion();
189
Pavithra Barithaya9e6631e2024-01-22 00:46:32 -0600190 /* @brief Method to resize the table
191 *
192 * @return resized table
193 */
194 std::vector<uint8_t> tableResize();
195
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500196 /* @brief set FRU Record Table
197 *
198 * @param[in] fruData - the data of the fru
199 *
200 * @return PLDM completion code
201 */
202 int setFRUTable(const std::vector<uint8_t>& fruData);
203
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500204 private:
205 uint16_t nextRSI()
206 {
207 return ++rsi;
208 }
209
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600210 uint32_t nextRecordHandle()
211 {
212 return ++rh;
213 }
214
215 uint32_t rh = 0;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500216 uint16_t rsi = 0;
217 uint16_t numRecs = 0;
218 uint8_t padBytes = 0;
219 std::vector<uint8_t> table;
220 uint32_t checksum = 0;
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530221 bool isBuilt = false;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500222
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530223 fru_parser::FruParser parser;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500224 pldm_pdr* pdrRepo;
225 pldm_entity_association_tree* entityTree;
Sampa Misrac073a202021-05-08 10:56:05 -0500226 pldm_entity_association_tree* bmcEntityTree;
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500227 pldm::responder::oem_fru::Handler* oemFruHandler;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500228
229 std::map<dbus::ObjectPath, pldm_entity_node*> objToEntityNode{};
230
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500231 /** @brief populateRecord builds the FRU records for an instance of FRU and
232 * updates the FRU table with the FRU records.
233 *
234 * @param[in] interfaces - D-Bus interfaces and the associated property
235 * values for the FRU
236 * @param[in] recordInfos - FRU record info to build the FRU records
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500237 * @param[in/out] entity - PLDM entity corresponding to FRU instance
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500238 */
George Liuc4ea6a92020-07-14 15:48:44 +0800239 void populateRecords(const dbus::InterfaceMap& interfaces,
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500240 const fru_parser::FruRecordInfos& recordInfos,
241 const pldm_entity& entity);
George Liuc4ea6a92020-07-14 15:48:44 +0800242
243 /** @brief Associate sensor/effecter to FRU entity
244 */
245 dbus::AssociatedEntityMap associatedEntityMap;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500246};
247
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500248namespace fru
249{
250
251class Handler : public CmdHandler
252{
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500253 public:
Manojkiran Eda03b01ca2021-06-29 08:55:09 +0530254 Handler(const std::string& configPath,
255 const std::filesystem::path& fruMasterJsonPath, pldm_pdr* pdrRepo,
Sampa Misrac073a202021-05-08 10:56:05 -0500256 pldm_entity_association_tree* entityTree,
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500257 pldm_entity_association_tree* bmcEntityTree,
258 pldm::responder::oem_fru::Handler* oemFruHandler) :
259 impl(configPath, fruMasterJsonPath, pdrRepo, entityTree, bmcEntityTree,
260 oemFruHandler)
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500261 {
Delphine CC Chiud2e48992023-12-05 16:29:51 +0800262 handlers.emplace(
263 PLDM_GET_FRU_RECORD_TABLE_METADATA,
264 [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500265 return this->getFRURecordTableMetadata(request, payloadLength);
266 });
Delphine CC Chiud2e48992023-12-05 16:29:51 +0800267 handlers.emplace(
268 PLDM_GET_FRU_RECORD_TABLE,
269 [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500270 return this->getFRURecordTable(request, payloadLength);
271 });
Delphine CC Chiud2e48992023-12-05 16:29:51 +0800272 handlers.emplace(
273 PLDM_GET_FRU_RECORD_BY_OPTION,
274 [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500275 return this->getFRURecordByOption(request, payloadLength);
276 });
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500277 handlers.emplace(
278 PLDM_SET_FRU_RECORD_TABLE,
279 [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
280 return this->setFRURecordTable(request, payloadLength);
281 });
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500282 }
283
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500284 /** @brief Handler for Get FRURecordTableMetadata
285 *
286 * @param[in] request - Request message payload
287 * @param[in] payloadLength - Request payload length
288 *
289 * @return PLDM response message
290 */
291 Response getFRURecordTableMetadata(const pldm_msg* request,
292 size_t payloadLength);
293
294 /** @brief Handler for GetFRURecordTable
295 *
296 * @param[in] request - Request message payload
297 * @param[in] payloadLength - Request payload length
298 *
299 * @return PLDM response message
300 */
301 Response getFRURecordTable(const pldm_msg* request, size_t payloadLength);
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500302
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530303 /** @brief Build FRU table is bnot already built
304 *
305 */
306 void buildFRUTable()
307 {
308 impl.buildFRUTable();
309 }
310
George Liuc4ea6a92020-07-14 15:48:44 +0800311 /** @brief Get std::map associated with the entity
312 * key: object path
313 * value: pldm_entity
314 *
315 * @return std::map<ObjectPath, pldm_entity>
316 */
317 const pldm::responder::dbus::AssociatedEntityMap&
318 getAssociateEntityMap() const
319 {
320 return impl.getAssociateEntityMap();
321 }
322
John Wang9e82ad12020-06-12 10:53:32 +0800323 /** @brief Handler for GetFRURecordByOption
324 *
325 * @param[in] request - Request message payload
326 * @param[in] payloadLength - Request payload length
327 *
328 * @return PLDM response message
329 */
330 Response getFRURecordByOption(const pldm_msg* request,
331 size_t payloadLength);
332
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500333 /** @brief Handler for SetFRURecordTable
334 *
335 * @param[in] request - Request message
336 * @param[in] payloadLength - Request payload length
337 *
338 * @return PLDM response message
339 */
340 Response setFRURecordTable(const pldm_msg* request, size_t payloadLength);
341
342 using Table = std::vector<uint8_t>;
343
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500344 private:
345 FruImpl impl;
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500346};
347
348} // namespace fru
349
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500350} // namespace responder
351
352} // namespace pldm