blob: b986836575a79ba04349b0bdfbb63744c0ceaa8d [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"
Deepak Kodihalli1521f6d2020-06-16 08:51:02 -05004#include "pldmd/handler.hpp"
Deepak Kodihalli70e8db02019-10-21 00:59:46 -05005
George Liuc453e162022-12-21 17:16:23 +08006#include <libpldm/fru.h>
7#include <libpldm/pdr.h>
8
Deepak Kodihalli70e8db02019-10-21 00:59:46 -05009#include <sdbusplus/message.hpp>
George Liu6492f522020-06-16 10:34:05 +080010
11#include <map>
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050012#include <string>
13#include <variant>
14#include <vector>
15
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050016namespace pldm
17{
18
19namespace responder
20{
21
22namespace dbus
23{
24
25using Value =
26 std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
27 uint64_t, double, std::string, std::vector<uint8_t>>;
28using PropertyMap = std::map<Property, Value>;
29using InterfaceMap = std::map<Interface, PropertyMap>;
30using ObjectValueTree = std::map<sdbusplus::message::object_path, InterfaceMap>;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -050031using ObjectPath = std::string;
George Liuc4ea6a92020-07-14 15:48:44 +080032using AssociatedEntityMap = std::map<ObjectPath, pldm_entity>;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050033
34} // namespace dbus
35
36/** @class FruImpl
37 *
38 * @brief Builds the PLDM FRU table containing the FRU records
39 */
40class FruImpl
41{
42 public:
43 /* @brief Header size for FRU record, it includes the FRU record set
44 * identifier, FRU record type, Number of FRU fields, Encoding type
45 * of FRU fields
46 */
47 static constexpr size_t recHeaderSize =
48 sizeof(struct pldm_fru_record_data_format) -
49 sizeof(struct pldm_fru_record_tlv);
50
Tom Joseph33e9c7e2020-06-11 22:09:52 +053051 /** @brief Constructor for FruImpl, the configPath is consumed to build the
52 * FruParser object.
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050053 *
54 * @param[in] configPath - path to the directory containing config files
Tom Joseph33e9c7e2020-06-11 22:09:52 +053055 * for PLDM FRU
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053056 * @param[in] fruMasterJsonPath - path to the file containing the FRU D-Bus
57 * Lookup Map
Tom Joseph33e9c7e2020-06-11 22:09:52 +053058 * @param[in] pdrRepo - opaque pointer to PDR repository
59 * @param[in] entityTree - opaque pointer to the entity association tree
Sampa Misrac073a202021-05-08 10:56:05 -050060 * @param[in] bmcEntityTree - opaque pointer to bmc's entity association
61 * tree
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050062 */
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053063 FruImpl(const std::string& configPath,
64 const std::filesystem::path& fruMasterJsonPath, pldm_pdr* pdrRepo,
Sampa Misrac073a202021-05-08 10:56:05 -050065 pldm_entity_association_tree* entityTree,
66 pldm_entity_association_tree* bmcEntityTree) :
Manojkiran Eda03b01ca2021-06-29 08:55:09 +053067 parser(configPath, fruMasterJsonPath),
Sampa Misrac073a202021-05-08 10:56:05 -050068 pdrRepo(pdrRepo), entityTree(entityTree), bmcEntityTree(bmcEntityTree)
Tom Joseph33e9c7e2020-06-11 22:09:52 +053069 {}
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050070
71 /** @brief Total length of the FRU table in bytes, this excludes the pad
72 * bytes and the checksum.
73 *
74 * @return size of the FRU table
75 */
76 uint32_t size() const
77 {
78 return table.size() - padBytes;
79 }
80
81 /** @brief The checksum of the contents of the FRU table
82 *
83 * @return checksum
84 */
85 uint32_t checkSum() const
86 {
87 return checksum;
88 }
89
90 /** @brief Number of record set identifiers in the FRU tables
91 *
92 * @return number of record set identifiers
93 */
94 uint16_t numRSI() const
95 {
96 return rsi;
97 }
98
99 /** @brief The number of FRU records in the table
100 *
101 * @return number of FRU records
102 */
103 uint16_t numRecords() const
104 {
105 return numRecs;
106 }
107
108 /** @brief Get the FRU table
109 *
110 * @param[out] - Populate response with the FRU table
111 */
112 void getFRUTable(Response& response);
113
John Wang9e82ad12020-06-12 10:53:32 +0800114 /** @brief Get FRU Record Table By Option
115 * @param[out] response - Populate response with the FRU table got by
116 * options
117 * @param[in] fruTableHandle - The fru table handle
118 * @param[in] recordSetIdentifer - The record set identifier
119 * @param[in] recordType - The record type
120 * @param[in] fieldType - The field type
121 */
122 int getFRURecordByOption(Response& response, uint16_t fruTableHandle,
123 uint16_t recordSetIdentifer, uint8_t recordType,
124 uint8_t fieldType);
125
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530126 /** @brief FRU table is built by processing the D-Bus inventory namespace
127 * based on the config files for FRU. The table is populated based
128 * on the isBuilt flag.
129 */
130 void buildFRUTable();
131
George Liuc4ea6a92020-07-14 15:48:44 +0800132 /** @brief Get std::map associated with the entity
133 * key: object path
134 * value: pldm_entity
135 *
136 * @return std::map<ObjectPath, pldm_entity>
137 */
138 inline const pldm::responder::dbus::AssociatedEntityMap&
139 getAssociateEntityMap() const
140 {
141 return associatedEntityMap;
142 }
143
George Liu5bfb0dc2021-05-01 14:28:41 +0800144 /** @brief Get pldm entity by the object path
145 *
146 * @param[in] intfMaps - D-Bus interfaces and the associated property
147 * values for the FRU
148 *
149 * @return pldm_entity
150 */
151 std::optional<pldm_entity>
152 getEntityByObjectPath(const dbus::InterfaceMap& intfMaps);
153
154 /** @brief Update pldm entity to association tree
155 *
156 * @param[in] objects - std::map The object value tree
157 * @param[in] path - Object path
158 *
159 * Ex: Input path =
160 * "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
161 *
162 * Get the parent class in turn and store it in a temporary vector
163 *
164 * Output tmpObjPaths = {
165 * "/xyz/openbmc_project/inventory/system",
166 * "/xyz/openbmc_project/inventory/system/chassis/",
167 * "/xyz/openbmc_project/inventory/system/chassis/motherboard",
168 * "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"}
169 *
170 */
171 void updateAssociationTree(const dbus::ObjectValueTree& objects,
172 const std::string& path);
173
Pavithra Barithaya47180ac2020-10-28 02:12:05 -0500174 /* @brief Method to populate the firmware version ID
175 *
176 * @return firmware version ID
177 */
178 std::string populatefwVersion();
179
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500180 private:
181 uint16_t nextRSI()
182 {
183 return ++rsi;
184 }
185
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600186 uint32_t nextRecordHandle()
187 {
188 return ++rh;
189 }
190
191 uint32_t rh = 0;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500192 uint16_t rsi = 0;
193 uint16_t numRecs = 0;
194 uint8_t padBytes = 0;
195 std::vector<uint8_t> table;
196 uint32_t checksum = 0;
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530197 bool isBuilt = false;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500198
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530199 fru_parser::FruParser parser;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500200 pldm_pdr* pdrRepo;
201 pldm_entity_association_tree* entityTree;
Sampa Misrac073a202021-05-08 10:56:05 -0500202 pldm_entity_association_tree* bmcEntityTree;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500203
204 std::map<dbus::ObjectPath, pldm_entity_node*> objToEntityNode{};
205
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500206 /** @brief populateRecord builds the FRU records for an instance of FRU and
207 * updates the FRU table with the FRU records.
208 *
209 * @param[in] interfaces - D-Bus interfaces and the associated property
210 * values for the FRU
211 * @param[in] recordInfos - FRU record info to build the FRU records
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500212 * @param[in/out] entity - PLDM entity corresponding to FRU instance
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500213 */
George Liuc4ea6a92020-07-14 15:48:44 +0800214 void populateRecords(const dbus::InterfaceMap& interfaces,
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500215 const fru_parser::FruRecordInfos& recordInfos,
216 const pldm_entity& entity);
George Liuc4ea6a92020-07-14 15:48:44 +0800217
218 /** @brief Associate sensor/effecter to FRU entity
219 */
220 dbus::AssociatedEntityMap associatedEntityMap;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500221};
222
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500223namespace fru
224{
225
226class Handler : public CmdHandler
227{
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500228 public:
Manojkiran Eda03b01ca2021-06-29 08:55:09 +0530229 Handler(const std::string& configPath,
230 const std::filesystem::path& fruMasterJsonPath, pldm_pdr* pdrRepo,
Sampa Misrac073a202021-05-08 10:56:05 -0500231 pldm_entity_association_tree* entityTree,
232 pldm_entity_association_tree* bmcEntityTree) :
Manojkiran Eda03b01ca2021-06-29 08:55:09 +0530233 impl(configPath, fruMasterJsonPath, pdrRepo, entityTree, bmcEntityTree)
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500234 {
235 handlers.emplace(PLDM_GET_FRU_RECORD_TABLE_METADATA,
236 [this](const pldm_msg* request, size_t payloadLength) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500237 return this->getFRURecordTableMetadata(request, payloadLength);
238 });
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500239
240 handlers.emplace(PLDM_GET_FRU_RECORD_TABLE,
241 [this](const pldm_msg* request, size_t payloadLength) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500242 return this->getFRURecordTable(request, payloadLength);
243 });
John Wang9e82ad12020-06-12 10:53:32 +0800244 handlers.emplace(PLDM_GET_FRU_RECORD_BY_OPTION,
245 [this](const pldm_msg* request, size_t payloadLength) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500246 return this->getFRURecordByOption(request, payloadLength);
247 });
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500248 }
249
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500250 /** @brief Handler for Get FRURecordTableMetadata
251 *
252 * @param[in] request - Request message payload
253 * @param[in] payloadLength - Request payload length
254 *
255 * @return PLDM response message
256 */
257 Response getFRURecordTableMetadata(const pldm_msg* request,
258 size_t payloadLength);
259
260 /** @brief Handler for GetFRURecordTable
261 *
262 * @param[in] request - Request message payload
263 * @param[in] payloadLength - Request payload length
264 *
265 * @return PLDM response message
266 */
267 Response getFRURecordTable(const pldm_msg* request, size_t payloadLength);
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500268
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530269 /** @brief Build FRU table is bnot already built
270 *
271 */
272 void buildFRUTable()
273 {
274 impl.buildFRUTable();
275 }
276
George Liuc4ea6a92020-07-14 15:48:44 +0800277 /** @brief Get std::map associated with the entity
278 * key: object path
279 * value: pldm_entity
280 *
281 * @return std::map<ObjectPath, pldm_entity>
282 */
283 const pldm::responder::dbus::AssociatedEntityMap&
284 getAssociateEntityMap() const
285 {
286 return impl.getAssociateEntityMap();
287 }
288
John Wang9e82ad12020-06-12 10:53:32 +0800289 /** @brief Handler for GetFRURecordByOption
290 *
291 * @param[in] request - Request message payload
292 * @param[in] payloadLength - Request payload length
293 *
294 * @return PLDM response message
295 */
296 Response getFRURecordByOption(const pldm_msg* request,
297 size_t payloadLength);
298
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500299 private:
300 FruImpl impl;
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500301};
302
303} // namespace fru
304
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500305} // namespace responder
306
307} // namespace pldm