xref: /openbmc/pldm/libpldmresponder/fru.hpp (revision 579a34a3)
1 #pragma once
2 
3 #include "config.h"
4 
5 #include "libpldm/fru.h"
6 #include "libpldm/pdr.h"
7 
8 #include "fru_parser.hpp"
9 #include "pldmd/handler.hpp"
10 
11 #include <sdbusplus/message.hpp>
12 
13 #include <map>
14 #include <string>
15 #include <variant>
16 #include <vector>
17 
18 namespace pldm
19 {
20 
21 namespace responder
22 {
23 
24 namespace dbus
25 {
26 
27 using 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>>;
30 using PropertyMap = std::map<Property, Value>;
31 using InterfaceMap = std::map<Interface, PropertyMap>;
32 using ObjectValueTree = std::map<sdbusplus::message::object_path, InterfaceMap>;
33 using ObjectPath = std::string;
34 
35 } // namespace dbus
36 
37 /** @class FruImpl
38  *
39  *  @brief Builds the PLDM FRU table containing the FRU records
40  */
41 class FruImpl
42 {
43   public:
44     /* @brief Header size for FRU record, it includes the FRU record set
45      *        identifier, FRU record type, Number of FRU fields, Encoding type
46      *        of FRU fields
47      */
48     static constexpr size_t recHeaderSize =
49         sizeof(struct pldm_fru_record_data_format) -
50         sizeof(struct pldm_fru_record_tlv);
51 
52     /** @brief Constructor for FruImpl, the configPath is consumed to build the
53      *         FruParser object.
54      *
55      *  @param[in] configPath - path to the directory containing config files
56      *                          for PLDM FRU
57      *  @param[in] pdrRepo - opaque pointer to PDR repository
58      *  @param[in] entityTree - opaque pointer to the entity association tree
59      */
60     FruImpl(const std::string& configPath, pldm_pdr* pdrRepo,
61             pldm_entity_association_tree* entityTree) :
62         parser(configPath),
63         pdrRepo(pdrRepo), entityTree(entityTree)
64     {}
65 
66     /** @brief Total length of the FRU table in bytes, this excludes the pad
67      *         bytes and the checksum.
68      *
69      *  @return size of the FRU table
70      */
71     uint32_t size() const
72     {
73         return table.size() - padBytes;
74     }
75 
76     /** @brief The checksum of the contents of the FRU table
77      *
78      *  @return checksum
79      */
80     uint32_t checkSum() const
81     {
82         return checksum;
83     }
84 
85     /** @brief Number of record set identifiers in the FRU tables
86      *
87      *  @return number of record set identifiers
88      */
89     uint16_t numRSI() const
90     {
91         return rsi;
92     }
93 
94     /** @brief The number of FRU records in the table
95      *
96      *  @return number of FRU records
97      */
98     uint16_t numRecords() const
99     {
100         return numRecs;
101     }
102 
103     /** @brief Get the FRU table
104      *
105      *  @param[out] - Populate response with the FRU table
106      */
107     void getFRUTable(Response& response);
108 
109     /** @brief FRU table is built by processing the D-Bus inventory namespace
110      *         based on the config files for FRU. The table is populated based
111      *         on the isBuilt flag.
112      */
113     void buildFRUTable();
114 
115   private:
116     uint16_t nextRSI()
117     {
118         return ++rsi;
119     }
120 
121     uint16_t rsi = 0;
122     uint16_t numRecs = 0;
123     uint8_t padBytes = 0;
124     std::vector<uint8_t> table;
125     uint32_t checksum = 0;
126     bool isBuilt = false;
127 
128     fru_parser::FruParser parser;
129     pldm_pdr* pdrRepo;
130     pldm_entity_association_tree* entityTree;
131 
132     std::map<dbus::ObjectPath, pldm_entity_node*> objToEntityNode{};
133 
134     /** @brief populateRecord builds the FRU records for an instance of FRU and
135      *         updates the FRU table with the FRU records.
136      *
137      *  @param[in] interfaces - D-Bus interfaces and the associated property
138      *                          values for the FRU
139      *  @param[in] recordInfos - FRU record info to build the FRU records
140      *  @param[in/out] entity - PLDM entity corresponding to FRU instance
141      */
142     void populateRecords(const pldm::responder::dbus::InterfaceMap& interfaces,
143                          const fru_parser::FruRecordInfos& recordInfos,
144                          const pldm_entity& entity);
145 };
146 
147 namespace fru
148 {
149 
150 class Handler : public CmdHandler
151 {
152 
153   public:
154     Handler(const std::string& configPath, pldm_pdr* pdrRepo,
155             pldm_entity_association_tree* entityTree) :
156         impl(configPath, pdrRepo, entityTree)
157     {
158         handlers.emplace(PLDM_GET_FRU_RECORD_TABLE_METADATA,
159                          [this](const pldm_msg* request, size_t payloadLength) {
160                              return this->getFRURecordTableMetadata(
161                                  request, payloadLength);
162                          });
163 
164         handlers.emplace(PLDM_GET_FRU_RECORD_TABLE,
165                          [this](const pldm_msg* request, size_t payloadLength) {
166                              return this->getFRURecordTable(request,
167                                                             payloadLength);
168                          });
169     }
170 
171     /** @brief Handler for Get FRURecordTableMetadata
172      *
173      *  @param[in] request - Request message payload
174      *  @param[in] payloadLength - Request payload length
175      *
176      *  @return PLDM response message
177      */
178     Response getFRURecordTableMetadata(const pldm_msg* request,
179                                        size_t payloadLength);
180 
181     /** @brief Handler for GetFRURecordTable
182      *
183      *  @param[in] request - Request message payload
184      *  @param[in] payloadLength - Request payload length
185      *
186      *  @return PLDM response message
187      */
188     Response getFRURecordTable(const pldm_msg* request, size_t payloadLength);
189 
190     /** @brief Build FRU table is bnot already built
191      *
192      */
193     void buildFRUTable()
194     {
195         impl.buildFRUTable();
196     }
197 
198   private:
199     FruImpl impl;
200 };
201 
202 } // namespace fru
203 
204 } // namespace responder
205 
206 } // namespace pldm
207