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 Get FRU Record Table By Option 110 * @param[out] response - Populate response with the FRU table got by 111 * options 112 * @param[in] fruTableHandle - The fru table handle 113 * @param[in] recordSetIdentifer - The record set identifier 114 * @param[in] recordType - The record type 115 * @param[in] fieldType - The field type 116 */ 117 int getFRURecordByOption(Response& response, uint16_t fruTableHandle, 118 uint16_t recordSetIdentifer, uint8_t recordType, 119 uint8_t fieldType); 120 121 /** @brief FRU table is built by processing the D-Bus inventory namespace 122 * based on the config files for FRU. The table is populated based 123 * on the isBuilt flag. 124 */ 125 void buildFRUTable(); 126 127 private: 128 uint16_t nextRSI() 129 { 130 return ++rsi; 131 } 132 133 uint16_t rsi = 0; 134 uint16_t numRecs = 0; 135 uint8_t padBytes = 0; 136 std::vector<uint8_t> table; 137 uint32_t checksum = 0; 138 bool isBuilt = false; 139 140 fru_parser::FruParser parser; 141 pldm_pdr* pdrRepo; 142 pldm_entity_association_tree* entityTree; 143 144 std::map<dbus::ObjectPath, pldm_entity_node*> objToEntityNode{}; 145 146 /** @brief populateRecord builds the FRU records for an instance of FRU and 147 * updates the FRU table with the FRU records. 148 * 149 * @param[in] interfaces - D-Bus interfaces and the associated property 150 * values for the FRU 151 * @param[in] recordInfos - FRU record info to build the FRU records 152 * @param[in/out] entity - PLDM entity corresponding to FRU instance 153 */ 154 void populateRecords(const pldm::responder::dbus::InterfaceMap& interfaces, 155 const fru_parser::FruRecordInfos& recordInfos, 156 const pldm_entity& entity); 157 }; 158 159 namespace fru 160 { 161 162 class Handler : public CmdHandler 163 { 164 165 public: 166 Handler(const std::string& configPath, pldm_pdr* pdrRepo, 167 pldm_entity_association_tree* entityTree) : 168 impl(configPath, pdrRepo, entityTree) 169 { 170 handlers.emplace(PLDM_GET_FRU_RECORD_TABLE_METADATA, 171 [this](const pldm_msg* request, size_t payloadLength) { 172 return this->getFRURecordTableMetadata( 173 request, payloadLength); 174 }); 175 176 handlers.emplace(PLDM_GET_FRU_RECORD_TABLE, 177 [this](const pldm_msg* request, size_t payloadLength) { 178 return this->getFRURecordTable(request, 179 payloadLength); 180 }); 181 handlers.emplace(PLDM_GET_FRU_RECORD_BY_OPTION, 182 [this](const pldm_msg* request, size_t payloadLength) { 183 return this->getFRURecordByOption(request, 184 payloadLength); 185 }); 186 } 187 188 /** @brief Handler for Get FRURecordTableMetadata 189 * 190 * @param[in] request - Request message payload 191 * @param[in] payloadLength - Request payload length 192 * 193 * @return PLDM response message 194 */ 195 Response getFRURecordTableMetadata(const pldm_msg* request, 196 size_t payloadLength); 197 198 /** @brief Handler for GetFRURecordTable 199 * 200 * @param[in] request - Request message payload 201 * @param[in] payloadLength - Request payload length 202 * 203 * @return PLDM response message 204 */ 205 Response getFRURecordTable(const pldm_msg* request, size_t payloadLength); 206 207 /** @brief Build FRU table is bnot already built 208 * 209 */ 210 void buildFRUTable() 211 { 212 impl.buildFRUTable(); 213 } 214 215 /** @brief Handler for GetFRURecordByOption 216 * 217 * @param[in] request - Request message payload 218 * @param[in] payloadLength - Request payload length 219 * 220 * @return PLDM response message 221 */ 222 Response getFRURecordByOption(const pldm_msg* request, 223 size_t payloadLength); 224 225 private: 226 FruImpl impl; 227 }; 228 229 } // namespace fru 230 231 } // namespace responder 232 233 } // namespace pldm 234