| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 1 | #pragma once | 
 | 2 |  | 
| Deepak Kodihalli | d130e1a | 2020-06-17 05:55:32 -0500 | [diff] [blame] | 3 | #include "common/types.hpp" | 
 | 4 | #include "common/utils.hpp" | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame] | 5 |  | 
| George Liu | c453e16 | 2022-12-21 17:16:23 +0800 | [diff] [blame] | 6 | #include <libpldm/pdr.h> | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 7 | #include <stdint.h> | 
 | 8 |  | 
| George Liu | 6492f52 | 2020-06-16 10:34:05 +0800 | [diff] [blame] | 9 | #include <nlohmann/json.hpp> | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 10 | #include <phosphor-logging/lg2.hpp> | 
| George Liu | 6492f52 | 2020-06-16 10:34:05 +0800 | [diff] [blame] | 11 | #include <xyz/openbmc_project/Common/error.hpp> | 
 | 12 |  | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 13 | #include <filesystem> | 
 | 14 | #include <fstream> | 
 | 15 | #include <functional> | 
 | 16 | #include <iostream> | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 17 | #include <string> | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 18 |  | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 19 | PHOSPHOR_LOG2_USING; | 
 | 20 |  | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 21 | using InternalFailure = | 
 | 22 |     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; | 
 | 23 |  | 
 | 24 | namespace fs = std::filesystem; | 
 | 25 |  | 
 | 26 | namespace pldm | 
 | 27 | { | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 28 | namespace responder | 
 | 29 | { | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 30 | namespace pdr_utils | 
 | 31 | { | 
| George Liu | adbe172 | 2020-05-09 19:20:19 +0800 | [diff] [blame] | 32 | /** @struct Type ID associated with pdr | 
 | 33 |  * | 
 | 34 |  */ | 
 | 35 | enum class TypeId | 
 | 36 | { | 
 | 37 |     PLDM_EFFECTER_ID, | 
 | 38 |     PLDM_SENSOR_ID | 
 | 39 | }; | 
 | 40 |  | 
| George Liu | 682ee18 | 2020-12-25 15:24:33 +0800 | [diff] [blame] | 41 | struct FruTLV | 
 | 42 | { | 
 | 43 |     uint8_t fruFieldType; | 
 | 44 |     uint8_t fruFieldLen; | 
 | 45 |     std::vector<uint8_t> fruFieldValue; | 
 | 46 | }; | 
 | 47 |  | 
 | 48 | struct FruRecordDataFormat | 
 | 49 | { | 
 | 50 |     uint16_t fruRSI; | 
 | 51 |     uint8_t fruRecType; | 
 | 52 |     uint8_t fruNum; | 
 | 53 |     uint8_t fruEncodeType; | 
 | 54 |     std::vector<FruTLV> fruTLV; | 
 | 55 | }; | 
 | 56 |  | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 57 | /** @struct PdrEntry | 
 | 58 |  *  PDR entry structure that acts as a PDR record structure in the PDR | 
 | 59 |  *  repository to handle PDR APIs. | 
 | 60 |  */ | 
 | 61 | struct PdrEntry | 
 | 62 | { | 
 | 63 |     uint8_t* data; | 
 | 64 |     uint32_t size; | 
 | 65 |     union | 
 | 66 |     { | 
 | 67 |         uint32_t recordHandle; | 
 | 68 |         uint32_t nextRecordHandle; | 
 | 69 |     } handle; | 
 | 70 | }; | 
 | 71 | using Type = uint8_t; | 
 | 72 | using Json = nlohmann::json; | 
 | 73 | using RecordHandle = uint32_t; | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame] | 74 | using State = uint8_t; | 
 | 75 | using PossibleValues = std::vector<uint8_t>; | 
 | 76 |  | 
 | 77 | /** @brief Map of DBus property State to attribute value | 
 | 78 |  */ | 
 | 79 | using StatestoDbusVal = std::map<State, pldm::utils::PropertyValue>; | 
| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 80 | using DbusMappings = std::vector<pldm::utils::DBusMapping>; | 
 | 81 | using DbusValMaps = std::vector<StatestoDbusVal>; | 
| Manojkiran Eda | ae933cc | 2024-02-21 17:19:21 +0530 | [diff] [blame] | 82 | using EventStates = std::array<uint8_t, 8>; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 83 |  | 
 | 84 | /** @brief Parse PDR JSON file and output Json object | 
 | 85 |  * | 
 | 86 |  *  @param[in] path - path of PDR JSON file | 
 | 87 |  * | 
 | 88 |  *  @return Json - Json object | 
 | 89 |  */ | 
 | 90 | inline Json readJson(const std::string& path) | 
 | 91 | { | 
 | 92 |     fs::path dir(path); | 
 | 93 |     if (!fs::exists(dir) || fs::is_empty(dir)) | 
 | 94 |     { | 
 | 95 |         throw InternalFailure(); | 
 | 96 |     } | 
 | 97 |  | 
 | 98 |     std::ifstream jsonFile(path); | 
 | 99 |     if (!jsonFile.is_open()) | 
 | 100 |     { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 101 |         error("Error opening PDR JSON file, PATH={JSON_PATH}", "JSON_PATH", | 
 | 102 |               path); | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 103 |         return {}; | 
 | 104 |     } | 
 | 105 |  | 
 | 106 |     return Json::parse(jsonFile); | 
 | 107 | } | 
 | 108 |  | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame] | 109 | /** @brief Populate the mapping between D-Bus property stateId and attribute | 
 | 110 |  *          value for the effecter PDR enumeration attribute. | 
 | 111 |  * | 
 | 112 |  *  @param[in] type - type of the D-Bus property | 
 | 113 |  *  @param[in] dBusValues - json array of D-Bus property values | 
 | 114 |  *  @param[in] pv - Possible values for the effecter PDR enumeration attribute | 
 | 115 |  * | 
 | 116 |  *  @return StatestoDbusVal - Map of D-Bus property stateId to attribute value | 
 | 117 |  */ | 
 | 118 | StatestoDbusVal populateMapping(const std::string& type, const Json& dBusValues, | 
 | 119 |                                 const PossibleValues& pv); | 
 | 120 |  | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 121 | /** | 
 | 122 |  *  @class RepoInterface | 
 | 123 |  * | 
 | 124 |  *  @brief Abstract class describing the interface API to the PDR repository, | 
 | 125 |  *         this class wraps operations used to handle the new PDR APIs. | 
 | 126 |  */ | 
 | 127 | class RepoInterface | 
 | 128 | { | 
 | 129 |   public: | 
| Patrick Williams | 6da4f91 | 2023-05-10 07:50:53 -0500 | [diff] [blame] | 130 |     RepoInterface(pldm_pdr* repo) : repo(repo) {} | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 131 |  | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 132 |     virtual ~RepoInterface() = default; | 
 | 133 |  | 
 | 134 |     /** @brief Get an opaque pldm_pdr structure | 
 | 135 |      * | 
 | 136 |      *  @return pldm_pdr - pldm_pdr structure | 
 | 137 |      */ | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 138 |     virtual pldm_pdr* getPdr() const = 0; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 139 |  | 
 | 140 |     /** @brief Add a PDR record to a PDR repository | 
 | 141 |      * | 
 | 142 |      *  @param[in] pdrEntry - PDR records entry(data, size, recordHandle) | 
 | 143 |      * | 
 | 144 |      *  @return uint32_t - record handle assigned to PDR record | 
 | 145 |      */ | 
 | 146 |     virtual RecordHandle addRecord(const PdrEntry& pdrEntry) = 0; | 
 | 147 |  | 
 | 148 |     /** @brief Get the first PDR record from a PDR repository | 
 | 149 |      * | 
 | 150 |      *  @param[in] pdrEntry - PDR records entry(data, size, nextRecordHandle) | 
 | 151 |      * | 
 | 152 |      *  @return opaque pointer acting as PDR record handle, will be NULL if | 
 | 153 |      *          record was not found | 
 | 154 |      */ | 
 | 155 |     virtual const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) = 0; | 
 | 156 |  | 
 | 157 |     /** @brief Get the next PDR record from a PDR repository | 
 | 158 |      * | 
 | 159 |      *  @param[in] currRecord - opaque pointer acting as a PDR record handle | 
 | 160 |      *  @param[in] pdrEntry - PDR records entry(data, size, nextRecordHandle) | 
 | 161 |      * | 
 | 162 |      *  @return opaque pointer acting as PDR record handle, will be NULL if | 
 | 163 |      *          record was not found | 
 | 164 |      */ | 
 | 165 |     virtual const pldm_pdr_record* | 
 | 166 |         getNextRecord(const pldm_pdr_record* currRecord, | 
 | 167 |                       PdrEntry& pdrEntry) = 0; | 
 | 168 |  | 
 | 169 |     /** @brief Get record handle of a PDR record | 
 | 170 |      * | 
 | 171 |      *  @param[in] record - opaque pointer acting as a PDR record handle | 
 | 172 |      * | 
 | 173 |      *  @return uint32_t - record handle assigned to PDR record; 0 if record is | 
 | 174 |      *                     not found | 
 | 175 |      */ | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 176 |     virtual uint32_t getRecordHandle(const pldm_pdr_record* record) const = 0; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 177 |  | 
 | 178 |     /** @brief Get number of records in a PDR repository | 
 | 179 |      * | 
 | 180 |      *  @return uint32_t - number of records | 
 | 181 |      */ | 
 | 182 |     virtual uint32_t getRecordCount() = 0; | 
 | 183 |  | 
 | 184 |     /** @brief Determine if records are empty in a PDR repository | 
 | 185 |      * | 
 | 186 |      *  @return bool - true means empty and false means not empty | 
 | 187 |      */ | 
 | 188 |     virtual bool empty() = 0; | 
 | 189 |  | 
 | 190 |   protected: | 
 | 191 |     pldm_pdr* repo; | 
 | 192 | }; | 
 | 193 |  | 
 | 194 | /** | 
 | 195 |  *  @class Repo | 
 | 196 |  * | 
 | 197 |  *  Wrapper class to handle the PDR APIs | 
 | 198 |  * | 
 | 199 |  *  This class wraps operations used to handle PDR APIs. | 
 | 200 |  */ | 
 | 201 | class Repo : public RepoInterface | 
 | 202 | { | 
 | 203 |   public: | 
| Patrick Williams | 6da4f91 | 2023-05-10 07:50:53 -0500 | [diff] [blame] | 204 |     Repo(pldm_pdr* repo) : RepoInterface(repo) {} | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 205 |  | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 206 |     pldm_pdr* getPdr() const override; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 207 |  | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 208 |     RecordHandle addRecord(const PdrEntry& pdrEntry) override; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 209 |  | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 210 |     const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) override; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 211 |  | 
 | 212 |     const pldm_pdr_record* getNextRecord(const pldm_pdr_record* currRecord, | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 213 |                                          PdrEntry& pdrEntry) override; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 214 |  | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 215 |     uint32_t getRecordHandle(const pldm_pdr_record* record) const override; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 216 |  | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 217 |     uint32_t getRecordCount() override; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 218 |  | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 219 |     bool empty() override; | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 220 | }; | 
 | 221 |  | 
| Tom Joseph | b426860 | 2020-04-17 17:20:45 +0530 | [diff] [blame] | 222 | /** @brief Parse the State Sensor PDR and return the parsed sensor info which | 
 | 223 |  *         will be used to lookup the sensor info in the PlatformEventMessage | 
 | 224 |  *         command of sensorEvent type. | 
 | 225 |  * | 
 | 226 |  *  @param[in] stateSensorPdr - state sensor PDR | 
 | 227 |  * | 
 | 228 |  *  @return terminus handle, sensor ID and parsed sensor info | 
 | 229 |  */ | 
| Brad Bishop | 5079ac4 | 2021-08-19 18:35:06 -0400 | [diff] [blame] | 230 | std::tuple<pldm::pdr::TerminusHandle, pldm::pdr::SensorID, | 
 | 231 |            pldm::pdr::SensorInfo> | 
| Tom Joseph | b426860 | 2020-04-17 17:20:45 +0530 | [diff] [blame] | 232 |     parseStateSensorPDR(const std::vector<uint8_t>& stateSensorPdr); | 
 | 233 |  | 
| George Liu | 682ee18 | 2020-12-25 15:24:33 +0800 | [diff] [blame] | 234 | /** @brief Parse FRU record table and return the vector of the FRU record data | 
 | 235 |  *         format structure | 
 | 236 |  * | 
 | 237 |  *  @param[in] fruData - fru data | 
 | 238 |  *  @param[in] fruLen  - fru len | 
 | 239 |  * | 
 | 240 |  *  @return std::vector<FruRecordDataFormat> - the vector of the FRU record data | 
 | 241 |  *          format structure | 
 | 242 |  */ | 
 | 243 | std::vector<FruRecordDataFormat> parseFruRecordTable(const uint8_t* fruData, | 
 | 244 |                                                      size_t fruLen); | 
 | 245 |  | 
| Archana Kakani | 6ece21fb | 2023-10-10 08:21:52 -0500 | [diff] [blame] | 246 | /** @brief Return the size of data type based on the effecterDataSize enum value | 
 | 247 |  * | 
 | 248 |  *  @param[in] effecterDataSize - Bitwidth and format of setting effecter value | 
 | 249 |  *  @return[out] Map the effecterDataSize enum value to datatype and return the | 
 | 250 |  *               size of dataType | 
 | 251 |  */ | 
 | 252 | size_t getEffecterDataSize(uint8_t effecterDataSize); | 
 | 253 |  | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 254 | } // namespace pdr_utils | 
 | 255 | } // namespace responder | 
 | 256 | } // namespace pldm |