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