1 #pragma once 2 3 #include "utils.hpp" 4 5 #include <stdint.h> 6 7 #include <filesystem> 8 #include <fstream> 9 #include <functional> 10 #include <iostream> 11 #include <nlohmann/json.hpp> 12 #include <string> 13 #include <xyz/openbmc_project/Common/error.hpp> 14 15 #include "libpldm/pdr.h" 16 17 using InternalFailure = 18 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 19 20 namespace fs = std::filesystem; 21 22 namespace pldm 23 { 24 25 namespace responder 26 { 27 28 namespace pdr_utils 29 { 30 31 /** @struct PdrEntry 32 * PDR entry structure that acts as a PDR record structure in the PDR 33 * repository to handle PDR APIs. 34 */ 35 struct PdrEntry 36 { 37 uint8_t* data; 38 uint32_t size; 39 union 40 { 41 uint32_t recordHandle; 42 uint32_t nextRecordHandle; 43 } handle; 44 }; 45 using Type = uint8_t; 46 using Json = nlohmann::json; 47 using RecordHandle = uint32_t; 48 using State = uint8_t; 49 using PossibleValues = std::vector<uint8_t>; 50 51 /** @brief Map of DBus property State to attribute value 52 */ 53 using StatestoDbusVal = std::map<State, pldm::utils::PropertyValue>; 54 using DbusMappings = std::vector<pldm::utils::DBusMapping>; 55 using DbusValMaps = std::vector<StatestoDbusVal>; 56 57 /** @brief Parse PDR JSON file and output Json object 58 * 59 * @param[in] path - path of PDR JSON file 60 * 61 * @return Json - Json object 62 */ 63 inline Json readJson(const std::string& path) 64 { 65 fs::path dir(path); 66 if (!fs::exists(dir) || fs::is_empty(dir)) 67 { 68 throw InternalFailure(); 69 } 70 71 std::ifstream jsonFile(path); 72 if (!jsonFile.is_open()) 73 { 74 std::cerr << "Error opening PDR JSON file, PATH=" << path << "\n"; 75 return {}; 76 } 77 78 return Json::parse(jsonFile); 79 } 80 81 /** @brief Populate the mapping between D-Bus property stateId and attribute 82 * value for the effecter PDR enumeration attribute. 83 * 84 * @param[in] type - type of the D-Bus property 85 * @param[in] dBusValues - json array of D-Bus property values 86 * @param[in] pv - Possible values for the effecter PDR enumeration attribute 87 * 88 * @return StatestoDbusVal - Map of D-Bus property stateId to attribute value 89 */ 90 StatestoDbusVal populateMapping(const std::string& type, const Json& dBusValues, 91 const PossibleValues& pv); 92 93 /** 94 * @class RepoInterface 95 * 96 * @brief Abstract class describing the interface API to the PDR repository, 97 * this class wraps operations used to handle the new PDR APIs. 98 */ 99 class RepoInterface 100 { 101 public: 102 RepoInterface(pldm_pdr* repo) : repo(repo) 103 { 104 } 105 106 virtual ~RepoInterface() = default; 107 108 /** @brief Get an opaque pldm_pdr structure 109 * 110 * @return pldm_pdr - pldm_pdr structure 111 */ 112 virtual pldm_pdr* getPdr() const = 0; 113 114 /** @brief Add a PDR record to a PDR repository 115 * 116 * @param[in] pdrEntry - PDR records entry(data, size, recordHandle) 117 * 118 * @return uint32_t - record handle assigned to PDR record 119 */ 120 virtual RecordHandle addRecord(const PdrEntry& pdrEntry) = 0; 121 122 /** @brief Get the first PDR record from a PDR repository 123 * 124 * @param[in] pdrEntry - PDR records entry(data, size, nextRecordHandle) 125 * 126 * @return opaque pointer acting as PDR record handle, will be NULL if 127 * record was not found 128 */ 129 virtual const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) = 0; 130 131 /** @brief Get the next PDR record from a PDR repository 132 * 133 * @param[in] currRecord - opaque pointer acting as a PDR record handle 134 * @param[in] pdrEntry - PDR records entry(data, size, nextRecordHandle) 135 * 136 * @return opaque pointer acting as PDR record handle, will be NULL if 137 * record was not found 138 */ 139 virtual const pldm_pdr_record* 140 getNextRecord(const pldm_pdr_record* currRecord, 141 PdrEntry& pdrEntry) = 0; 142 143 /** @brief Get record handle of a PDR record 144 * 145 * @param[in] record - opaque pointer acting as a PDR record handle 146 * 147 * @return uint32_t - record handle assigned to PDR record; 0 if record is 148 * not found 149 */ 150 virtual uint32_t getRecordHandle(const pldm_pdr_record* record) const = 0; 151 152 /** @brief Get number of records in a PDR repository 153 * 154 * @return uint32_t - number of records 155 */ 156 virtual uint32_t getRecordCount() = 0; 157 158 /** @brief Determine if records are empty in a PDR repository 159 * 160 * @return bool - true means empty and false means not empty 161 */ 162 virtual bool empty() = 0; 163 164 protected: 165 pldm_pdr* repo; 166 }; 167 168 /** 169 * @class Repo 170 * 171 * Wrapper class to handle the PDR APIs 172 * 173 * This class wraps operations used to handle PDR APIs. 174 */ 175 class Repo : public RepoInterface 176 { 177 public: 178 Repo(pldm_pdr* repo) : RepoInterface(repo) 179 { 180 } 181 182 pldm_pdr* getPdr() const override; 183 184 RecordHandle addRecord(const PdrEntry& pdrEntry) override; 185 186 const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) override; 187 188 const pldm_pdr_record* getNextRecord(const pldm_pdr_record* currRecord, 189 PdrEntry& pdrEntry) override; 190 191 uint32_t getRecordHandle(const pldm_pdr_record* record) const override; 192 193 uint32_t getRecordCount() override; 194 195 bool empty() override; 196 }; 197 198 } // namespace pdr_utils 199 } // namespace responder 200 } // namespace pldm 201