xref: /openbmc/pldm/libpldmresponder/fru.hpp (revision 1521f6d1)
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 The FRU table is populated by processing the D-Bus inventory
53      *         namespace, based on the config files for FRU. The configPath is
54      *         consumed to build the FruParser object.
55      *
56      *  @param[in] configPath - path to the directory containing config files
57      * for PLDM FRU
58      */
59     FruImpl(const std::string& configPath, pldm_pdr* pdrRepo,
60             pldm_entity_association_tree* entityTree);
61 
62     /** @brief Total length of the FRU table in bytes, this excludes the pad
63      *         bytes and the checksum.
64      *
65      *  @return size of the FRU table
66      */
67     uint32_t size() const
68     {
69         return table.size() - padBytes;
70     }
71 
72     /** @brief The checksum of the contents of the FRU table
73      *
74      *  @return checksum
75      */
76     uint32_t checkSum() const
77     {
78         return checksum;
79     }
80 
81     /** @brief Number of record set identifiers in the FRU tables
82      *
83      *  @return number of record set identifiers
84      */
85     uint16_t numRSI() const
86     {
87         return rsi;
88     }
89 
90     /** @brief The number of FRU records in the table
91      *
92      *  @return number of FRU records
93      */
94     uint16_t numRecords() const
95     {
96         return numRecs;
97     }
98 
99     /** @brief Get the FRU table
100      *
101      *  @param[out] - Populate response with the FRU table
102      */
103     void getFRUTable(Response& response);
104 
105   private:
106     uint16_t nextRSI()
107     {
108         return ++rsi;
109     }
110 
111     uint16_t rsi = 0;
112     uint16_t numRecs = 0;
113     uint8_t padBytes = 0;
114     std::vector<uint8_t> table;
115     uint32_t checksum = 0;
116 
117     pldm_pdr* pdrRepo;
118     pldm_entity_association_tree* entityTree;
119 
120     std::map<dbus::ObjectPath, pldm_entity_node*> objToEntityNode{};
121 
122     /** @brief populateRecord builds the FRU records for an instance of FRU and
123      *         updates the FRU table with the FRU records.
124      *
125      *  @param[in] interfaces - D-Bus interfaces and the associated property
126      *                          values for the FRU
127      *  @param[in] recordInfos - FRU record info to build the FRU records
128      *  @param[in/out] entity - PLDM entity corresponding to FRU instance
129      */
130     void populateRecords(const pldm::responder::dbus::InterfaceMap& interfaces,
131                          const fru_parser::FruRecordInfos& recordInfos,
132                          const pldm_entity& entity);
133 };
134 
135 namespace fru
136 {
137 
138 class Handler : public CmdHandler
139 {
140 
141   public:
142     Handler(const std::string& configPath, pldm_pdr* pdrRepo,
143             pldm_entity_association_tree* entityTree) :
144         impl(configPath, pdrRepo, entityTree)
145     {
146         handlers.emplace(PLDM_GET_FRU_RECORD_TABLE_METADATA,
147                          [this](const pldm_msg* request, size_t payloadLength) {
148                              return this->getFRURecordTableMetadata(
149                                  request, payloadLength);
150                          });
151 
152         handlers.emplace(PLDM_GET_FRU_RECORD_TABLE,
153                          [this](const pldm_msg* request, size_t payloadLength) {
154                              return this->getFRURecordTable(request,
155                                                             payloadLength);
156                          });
157     }
158 
159     /** @brief Handler for Get FRURecordTableMetadata
160      *
161      *  @param[in] request - Request message payload
162      *  @param[in] payloadLength - Request payload length
163      *
164      *  @return PLDM response message
165      */
166     Response getFRURecordTableMetadata(const pldm_msg* request,
167                                        size_t payloadLength);
168 
169     /** @brief Handler for GetFRURecordTable
170      *
171      *  @param[in] request - Request message payload
172      *  @param[in] payloadLength - Request payload length
173      *
174      *  @return PLDM response message
175      */
176     Response getFRURecordTable(const pldm_msg* request, size_t payloadLength);
177 
178   private:
179     FruImpl impl;
180 };
181 
182 } // namespace fru
183 
184 } // namespace responder
185 
186 } // namespace pldm
187