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