blob: 44dfff36755b52ac1e21ea3bf483d31755f89d46 [file] [log] [blame]
George Liue53193f2020-02-24 09:23:26 +08001#pragma once
2
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05003#include "common/types.hpp"
4#include "common/utils.hpp"
George Liu1ec85d42020-02-12 16:05:32 +08005
George Liuc453e162022-12-21 17:16:23 +08006#include <libpldm/pdr.h>
George Liue53193f2020-02-24 09:23:26 +08007#include <stdint.h>
8
George Liu6492f522020-06-16 10:34:05 +08009#include <nlohmann/json.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060010#include <phosphor-logging/lg2.hpp>
George Liu6492f522020-06-16 10:34:05 +080011#include <xyz/openbmc_project/Common/error.hpp>
12
George Liue53193f2020-02-24 09:23:26 +080013#include <filesystem>
14#include <fstream>
15#include <functional>
16#include <iostream>
George Liue53193f2020-02-24 09:23:26 +080017#include <string>
George Liue53193f2020-02-24 09:23:26 +080018
Riya Dixit49cfb132023-03-02 04:26:53 -060019PHOSPHOR_LOG2_USING;
20
George Liue53193f2020-02-24 09:23:26 +080021using InternalFailure =
22 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
23
24namespace fs = std::filesystem;
25
26namespace pldm
27{
George Liue53193f2020-02-24 09:23:26 +080028namespace responder
29{
George Liue53193f2020-02-24 09:23:26 +080030namespace pdr_utils
31{
George Liuadbe1722020-05-09 19:20:19 +080032/** @struct Type ID associated with pdr
33 *
34 */
35enum class TypeId
36{
37 PLDM_EFFECTER_ID,
38 PLDM_SENSOR_ID
39};
40
George Liu682ee182020-12-25 15:24:33 +080041struct FruTLV
42{
43 uint8_t fruFieldType;
44 uint8_t fruFieldLen;
45 std::vector<uint8_t> fruFieldValue;
46};
47
48struct 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 Liue53193f2020-02-24 09:23:26 +080057/** @struct PdrEntry
58 * PDR entry structure that acts as a PDR record structure in the PDR
59 * repository to handle PDR APIs.
60 */
61struct PdrEntry
62{
63 uint8_t* data;
64 uint32_t size;
65 union
66 {
67 uint32_t recordHandle;
68 uint32_t nextRecordHandle;
69 } handle;
70};
71using Type = uint8_t;
72using Json = nlohmann::json;
73using RecordHandle = uint32_t;
George Liu1ec85d42020-02-12 16:05:32 +080074using State = uint8_t;
75using PossibleValues = std::vector<uint8_t>;
76
77/** @brief Map of DBus property State to attribute value
78 */
79using StatestoDbusVal = std::map<State, pldm::utils::PropertyValue>;
George Liua2870722020-02-11 11:09:30 +080080using DbusMappings = std::vector<pldm::utils::DBusMapping>;
81using DbusValMaps = std::vector<StatestoDbusVal>;
Manojkiran Edaae933cc2024-02-21 17:19:21 +053082using EventStates = std::array<uint8_t, 8>;
George Liue53193f2020-02-24 09:23:26 +080083
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 */
90inline 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 Dixit49cfb132023-03-02 04:26:53 -0600101 error("Error opening PDR JSON file, PATH={JSON_PATH}", "JSON_PATH",
102 path);
George Liue53193f2020-02-24 09:23:26 +0800103 return {};
104 }
105
106 return Json::parse(jsonFile);
107}
108
George Liu1ec85d42020-02-12 16:05:32 +0800109/** @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 */
118StatestoDbusVal populateMapping(const std::string& type, const Json& dBusValues,
119 const PossibleValues& pv);
120
George Liue53193f2020-02-24 09:23:26 +0800121/**
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 */
127class RepoInterface
128{
129 public:
Patrick Williams6da4f912023-05-10 07:50:53 -0500130 RepoInterface(pldm_pdr* repo) : repo(repo) {}
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600131
George Liue53193f2020-02-24 09:23:26 +0800132 virtual ~RepoInterface() = default;
133
134 /** @brief Get an opaque pldm_pdr structure
135 *
136 * @return pldm_pdr - pldm_pdr structure
137 */
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600138 virtual pldm_pdr* getPdr() const = 0;
George Liue53193f2020-02-24 09:23:26 +0800139
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 Kodihallic682fe22020-03-04 00:42:54 -0600176 virtual uint32_t getRecordHandle(const pldm_pdr_record* record) const = 0;
George Liue53193f2020-02-24 09:23:26 +0800177
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 */
201class Repo : public RepoInterface
202{
203 public:
Patrick Williams6da4f912023-05-10 07:50:53 -0500204 Repo(pldm_pdr* repo) : RepoInterface(repo) {}
George Liue53193f2020-02-24 09:23:26 +0800205
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600206 pldm_pdr* getPdr() const override;
George Liue53193f2020-02-24 09:23:26 +0800207
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600208 RecordHandle addRecord(const PdrEntry& pdrEntry) override;
George Liue53193f2020-02-24 09:23:26 +0800209
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600210 const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) override;
George Liue53193f2020-02-24 09:23:26 +0800211
212 const pldm_pdr_record* getNextRecord(const pldm_pdr_record* currRecord,
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600213 PdrEntry& pdrEntry) override;
George Liue53193f2020-02-24 09:23:26 +0800214
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600215 uint32_t getRecordHandle(const pldm_pdr_record* record) const override;
George Liue53193f2020-02-24 09:23:26 +0800216
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600217 uint32_t getRecordCount() override;
George Liue53193f2020-02-24 09:23:26 +0800218
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600219 bool empty() override;
George Liue53193f2020-02-24 09:23:26 +0800220};
221
Tom Josephb4268602020-04-17 17:20:45 +0530222/** @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 Bishop5079ac42021-08-19 18:35:06 -0400230std::tuple<pldm::pdr::TerminusHandle, pldm::pdr::SensorID,
231 pldm::pdr::SensorInfo>
Tom Josephb4268602020-04-17 17:20:45 +0530232 parseStateSensorPDR(const std::vector<uint8_t>& stateSensorPdr);
233
George Liu682ee182020-12-25 15:24:33 +0800234/** @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 */
243std::vector<FruRecordDataFormat> parseFruRecordTable(const uint8_t* fruData,
244 size_t fruLen);
245
Archana Kakani6ece21fb2023-10-10 08:21:52 -0500246/** @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 */
252size_t getEffecterDataSize(uint8_t effecterDataSize);
253
George Liue53193f2020-02-24 09:23:26 +0800254} // namespace pdr_utils
255} // namespace responder
256} // namespace pldm