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