blob: 2843ee65742e72b5828e9875744a62f638fc3922 [file] [log] [blame]
George Liue53193f2020-02-24 09:23:26 +08001#pragma once
2
George Liu6492f522020-06-16 10:34:05 +08003#include "libpldm/pdr.h"
4
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05005#include "common/types.hpp"
6#include "common/utils.hpp"
George Liu1ec85d42020-02-12 16:05:32 +08007
George Liue53193f2020-02-24 09:23:26 +08008#include <stdint.h>
9
George Liu6492f522020-06-16 10:34:05 +080010#include <nlohmann/json.hpp>
11#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
19using InternalFailure =
20 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
21
22namespace fs = std::filesystem;
23
24namespace pldm
25{
26
27namespace responder
28{
29
30namespace pdr_utils
31{
32
33/** @struct PdrEntry
34 * PDR entry structure that acts as a PDR record structure in the PDR
35 * repository to handle PDR APIs.
36 */
37struct PdrEntry
38{
39 uint8_t* data;
40 uint32_t size;
41 union
42 {
43 uint32_t recordHandle;
44 uint32_t nextRecordHandle;
45 } handle;
46};
47using Type = uint8_t;
48using Json = nlohmann::json;
49using RecordHandle = uint32_t;
George Liu1ec85d42020-02-12 16:05:32 +080050using State = uint8_t;
51using PossibleValues = std::vector<uint8_t>;
52
53/** @brief Map of DBus property State to attribute value
54 */
55using StatestoDbusVal = std::map<State, pldm::utils::PropertyValue>;
George Liua2870722020-02-11 11:09:30 +080056using DbusMappings = std::vector<pldm::utils::DBusMapping>;
57using DbusValMaps = std::vector<StatestoDbusVal>;
George Liue53193f2020-02-24 09:23:26 +080058
59/** @brief Parse PDR JSON file and output Json object
60 *
61 * @param[in] path - path of PDR JSON file
62 *
63 * @return Json - Json object
64 */
65inline Json readJson(const std::string& path)
66{
67 fs::path dir(path);
68 if (!fs::exists(dir) || fs::is_empty(dir))
69 {
70 throw InternalFailure();
71 }
72
73 std::ifstream jsonFile(path);
74 if (!jsonFile.is_open())
75 {
76 std::cerr << "Error opening PDR JSON file, PATH=" << path << "\n";
77 return {};
78 }
79
80 return Json::parse(jsonFile);
81}
82
George Liu1ec85d42020-02-12 16:05:32 +080083/** @brief Populate the mapping between D-Bus property stateId and attribute
84 * value for the effecter PDR enumeration attribute.
85 *
86 * @param[in] type - type of the D-Bus property
87 * @param[in] dBusValues - json array of D-Bus property values
88 * @param[in] pv - Possible values for the effecter PDR enumeration attribute
89 *
90 * @return StatestoDbusVal - Map of D-Bus property stateId to attribute value
91 */
92StatestoDbusVal populateMapping(const std::string& type, const Json& dBusValues,
93 const PossibleValues& pv);
94
George Liue53193f2020-02-24 09:23:26 +080095/**
96 * @class RepoInterface
97 *
98 * @brief Abstract class describing the interface API to the PDR repository,
99 * this class wraps operations used to handle the new PDR APIs.
100 */
101class RepoInterface
102{
103 public:
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600104 RepoInterface(pldm_pdr* repo) : repo(repo)
George Liu6492f522020-06-16 10:34:05 +0800105 {}
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600106
George Liue53193f2020-02-24 09:23:26 +0800107 virtual ~RepoInterface() = default;
108
109 /** @brief Get an opaque pldm_pdr structure
110 *
111 * @return pldm_pdr - pldm_pdr structure
112 */
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600113 virtual pldm_pdr* getPdr() const = 0;
George Liue53193f2020-02-24 09:23:26 +0800114
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 */
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600151 virtual uint32_t getRecordHandle(const pldm_pdr_record* record) const = 0;
George Liue53193f2020-02-24 09:23:26 +0800152
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 */
176class Repo : public RepoInterface
177{
178 public:
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600179 Repo(pldm_pdr* repo) : RepoInterface(repo)
George Liu6492f522020-06-16 10:34:05 +0800180 {}
George Liue53193f2020-02-24 09:23:26 +0800181
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600182 pldm_pdr* getPdr() const override;
George Liue53193f2020-02-24 09:23:26 +0800183
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600184 RecordHandle addRecord(const PdrEntry& pdrEntry) override;
George Liue53193f2020-02-24 09:23:26 +0800185
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600186 const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) override;
George Liue53193f2020-02-24 09:23:26 +0800187
188 const pldm_pdr_record* getNextRecord(const pldm_pdr_record* currRecord,
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600189 PdrEntry& pdrEntry) override;
George Liue53193f2020-02-24 09:23:26 +0800190
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600191 uint32_t getRecordHandle(const pldm_pdr_record* record) const override;
George Liue53193f2020-02-24 09:23:26 +0800192
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600193 uint32_t getRecordCount() override;
George Liue53193f2020-02-24 09:23:26 +0800194
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600195 bool empty() override;
George Liue53193f2020-02-24 09:23:26 +0800196};
197
Tom Josephb4268602020-04-17 17:20:45 +0530198using namespace pldm::pdr;
199/** @brief Parse the State Sensor PDR and return the parsed sensor info which
200 * will be used to lookup the sensor info in the PlatformEventMessage
201 * command of sensorEvent type.
202 *
203 * @param[in] stateSensorPdr - state sensor PDR
204 *
205 * @return terminus handle, sensor ID and parsed sensor info
206 */
207std::tuple<TerminusHandle, SensorID, SensorInfo>
208 parseStateSensorPDR(const std::vector<uint8_t>& stateSensorPdr);
209
George Liue53193f2020-02-24 09:23:26 +0800210} // namespace pdr_utils
211} // namespace responder
212} // namespace pldm