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