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