blob: 18c7882bbde3c341655d35aaf1675f7fb719b0b4 [file] [log] [blame]
Deepak Kodihalli70e8db02019-10-21 00:59:46 -05001#pragma once
2
3#include "config.h"
4
George Liu6492f522020-06-16 10:34:05 +08005#include "libpldm/fru.h"
6#include "libpldm/pdr.h"
7
Deepak Kodihalli70e8db02019-10-21 00:59:46 -05008#include "fru_parser.hpp"
Deepak Kodihalli1521f6d2020-06-16 08:51:02 -05009#include "pldmd/handler.hpp"
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050010
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
58 * @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 */
Deepak Kodihalli3cd61812020-03-10 06:38:45 -050063 FruImpl(const std::string& configPath, pldm_pdr* pdrRepo,
Sampa Misrac073a202021-05-08 10:56:05 -050064 pldm_entity_association_tree* entityTree,
65 pldm_entity_association_tree* bmcEntityTree) :
Tom Joseph33e9c7e2020-06-11 22:09:52 +053066 parser(configPath),
Sampa Misrac073a202021-05-08 10:56:05 -050067 pdrRepo(pdrRepo), entityTree(entityTree), bmcEntityTree(bmcEntityTree)
Tom Joseph33e9c7e2020-06-11 22:09:52 +053068 {}
Deepak Kodihalli70e8db02019-10-21 00:59:46 -050069
70 /** @brief Total length of the FRU table in bytes, this excludes the pad
71 * bytes and the checksum.
72 *
73 * @return size of the FRU table
74 */
75 uint32_t size() const
76 {
77 return table.size() - padBytes;
78 }
79
80 /** @brief The checksum of the contents of the FRU table
81 *
82 * @return checksum
83 */
84 uint32_t checkSum() const
85 {
86 return checksum;
87 }
88
89 /** @brief Number of record set identifiers in the FRU tables
90 *
91 * @return number of record set identifiers
92 */
93 uint16_t numRSI() const
94 {
95 return rsi;
96 }
97
98 /** @brief The number of FRU records in the table
99 *
100 * @return number of FRU records
101 */
102 uint16_t numRecords() const
103 {
104 return numRecs;
105 }
106
107 /** @brief Get the FRU table
108 *
109 * @param[out] - Populate response with the FRU table
110 */
111 void getFRUTable(Response& response);
112
John Wang9e82ad12020-06-12 10:53:32 +0800113 /** @brief Get FRU Record Table By Option
114 * @param[out] response - Populate response with the FRU table got by
115 * options
116 * @param[in] fruTableHandle - The fru table handle
117 * @param[in] recordSetIdentifer - The record set identifier
118 * @param[in] recordType - The record type
119 * @param[in] fieldType - The field type
120 */
121 int getFRURecordByOption(Response& response, uint16_t fruTableHandle,
122 uint16_t recordSetIdentifer, uint8_t recordType,
123 uint8_t fieldType);
124
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530125 /** @brief FRU table is built by processing the D-Bus inventory namespace
126 * based on the config files for FRU. The table is populated based
127 * on the isBuilt flag.
128 */
129 void buildFRUTable();
130
George Liuc4ea6a92020-07-14 15:48:44 +0800131 /** @brief Get std::map associated with the entity
132 * key: object path
133 * value: pldm_entity
134 *
135 * @return std::map<ObjectPath, pldm_entity>
136 */
137 inline const pldm::responder::dbus::AssociatedEntityMap&
138 getAssociateEntityMap() const
139 {
140 return associatedEntityMap;
141 }
142
Pavithra Barithaya47180ac2020-10-28 02:12:05 -0500143 /* @brief Method to populate the firmware version ID
144 *
145 * @return firmware version ID
146 */
147 std::string populatefwVersion();
148
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500149 private:
150 uint16_t nextRSI()
151 {
152 return ++rsi;
153 }
154
155 uint16_t rsi = 0;
156 uint16_t numRecs = 0;
157 uint8_t padBytes = 0;
158 std::vector<uint8_t> table;
159 uint32_t checksum = 0;
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530160 bool isBuilt = false;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500161
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530162 fru_parser::FruParser parser;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500163 pldm_pdr* pdrRepo;
164 pldm_entity_association_tree* entityTree;
Sampa Misrac073a202021-05-08 10:56:05 -0500165 pldm_entity_association_tree* bmcEntityTree;
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500166
167 std::map<dbus::ObjectPath, pldm_entity_node*> objToEntityNode{};
168
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500169 /** @brief populateRecord builds the FRU records for an instance of FRU and
170 * updates the FRU table with the FRU records.
171 *
172 * @param[in] interfaces - D-Bus interfaces and the associated property
173 * values for the FRU
174 * @param[in] recordInfos - FRU record info to build the FRU records
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500175 * @param[in/out] entity - PLDM entity corresponding to FRU instance
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500176 */
George Liuc4ea6a92020-07-14 15:48:44 +0800177 void populateRecords(const dbus::InterfaceMap& interfaces,
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500178 const fru_parser::FruRecordInfos& recordInfos,
179 const pldm_entity& entity);
George Liuc4ea6a92020-07-14 15:48:44 +0800180
181 /** @brief Associate sensor/effecter to FRU entity
182 */
183 dbus::AssociatedEntityMap associatedEntityMap;
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500184};
185
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500186namespace fru
187{
188
189class Handler : public CmdHandler
190{
191
192 public:
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500193 Handler(const std::string& configPath, pldm_pdr* pdrRepo,
Sampa Misrac073a202021-05-08 10:56:05 -0500194 pldm_entity_association_tree* entityTree,
195 pldm_entity_association_tree* bmcEntityTree) :
196 impl(configPath, pdrRepo, entityTree, bmcEntityTree)
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500197 {
198 handlers.emplace(PLDM_GET_FRU_RECORD_TABLE_METADATA,
199 [this](const pldm_msg* request, size_t payloadLength) {
200 return this->getFRURecordTableMetadata(
201 request, payloadLength);
202 });
203
204 handlers.emplace(PLDM_GET_FRU_RECORD_TABLE,
205 [this](const pldm_msg* request, size_t payloadLength) {
206 return this->getFRURecordTable(request,
207 payloadLength);
208 });
John Wang9e82ad12020-06-12 10:53:32 +0800209 handlers.emplace(PLDM_GET_FRU_RECORD_BY_OPTION,
210 [this](const pldm_msg* request, size_t payloadLength) {
211 return this->getFRURecordByOption(request,
212 payloadLength);
213 });
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500214 }
215
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500216 /** @brief Handler for Get FRURecordTableMetadata
217 *
218 * @param[in] request - Request message payload
219 * @param[in] payloadLength - Request payload length
220 *
221 * @return PLDM response message
222 */
223 Response getFRURecordTableMetadata(const pldm_msg* request,
224 size_t payloadLength);
225
226 /** @brief Handler for GetFRURecordTable
227 *
228 * @param[in] request - Request message payload
229 * @param[in] payloadLength - Request payload length
230 *
231 * @return PLDM response message
232 */
233 Response getFRURecordTable(const pldm_msg* request, size_t payloadLength);
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500234
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530235 /** @brief Build FRU table is bnot already built
236 *
237 */
238 void buildFRUTable()
239 {
240 impl.buildFRUTable();
241 }
242
George Liuc4ea6a92020-07-14 15:48:44 +0800243 /** @brief Get std::map associated with the entity
244 * key: object path
245 * value: pldm_entity
246 *
247 * @return std::map<ObjectPath, pldm_entity>
248 */
249 const pldm::responder::dbus::AssociatedEntityMap&
250 getAssociateEntityMap() const
251 {
252 return impl.getAssociateEntityMap();
253 }
254
John Wang9e82ad12020-06-12 10:53:32 +0800255 /** @brief Handler for GetFRURecordByOption
256 *
257 * @param[in] request - Request message payload
258 * @param[in] payloadLength - Request payload length
259 *
260 * @return PLDM response message
261 */
262 Response getFRURecordByOption(const pldm_msg* request,
263 size_t payloadLength);
264
Deepak Kodihalli3cd61812020-03-10 06:38:45 -0500265 private:
266 FruImpl impl;
Deepak Kodihallie60c5822019-10-23 03:26:15 -0500267};
268
269} // namespace fru
270
Deepak Kodihalli70e8db02019-10-21 00:59:46 -0500271} // namespace responder
272
273} // namespace pldm