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