blob: 0c3f63483dc689b25e62be32af83e83c6f6e53ce [file] [log] [blame]
George Liue53193f2020-02-24 09:23:26 +08001#pragma once
2
3#include <stdint.h>
4
5#include <filesystem>
6#include <fstream>
7#include <functional>
8#include <iostream>
9#include <nlohmann/json.hpp>
10#include <string>
11#include <xyz/openbmc_project/Common/error.hpp>
12
13#include "libpldm/pdr.h"
14
15using InternalFailure =
16 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
17
18namespace fs = std::filesystem;
19
20namespace pldm
21{
22
23namespace responder
24{
25
26namespace pdr_utils
27{
28
29/** @struct PdrEntry
30 * PDR entry structure that acts as a PDR record structure in the PDR
31 * repository to handle PDR APIs.
32 */
33struct PdrEntry
34{
35 uint8_t* data;
36 uint32_t size;
37 union
38 {
39 uint32_t recordHandle;
40 uint32_t nextRecordHandle;
41 } handle;
42};
43using Type = uint8_t;
44using Json = nlohmann::json;
45using RecordHandle = uint32_t;
46
47/** @brief Parse PDR JSON file and output Json object
48 *
49 * @param[in] path - path of PDR JSON file
50 *
51 * @return Json - Json object
52 */
53inline Json readJson(const std::string& path)
54{
55 fs::path dir(path);
56 if (!fs::exists(dir) || fs::is_empty(dir))
57 {
58 throw InternalFailure();
59 }
60
61 std::ifstream jsonFile(path);
62 if (!jsonFile.is_open())
63 {
64 std::cerr << "Error opening PDR JSON file, PATH=" << path << "\n";
65 return {};
66 }
67
68 return Json::parse(jsonFile);
69}
70
71/**
72 * @class RepoInterface
73 *
74 * @brief Abstract class describing the interface API to the PDR repository,
75 * this class wraps operations used to handle the new PDR APIs.
76 */
77class RepoInterface
78{
79 public:
Deepak Kodihallic682fe22020-03-04 00:42:54 -060080 RepoInterface(pldm_pdr* repo) : repo(repo)
81 {
82 }
83
George Liue53193f2020-02-24 09:23:26 +080084 virtual ~RepoInterface() = default;
85
86 /** @brief Get an opaque pldm_pdr structure
87 *
88 * @return pldm_pdr - pldm_pdr structure
89 */
Deepak Kodihallic682fe22020-03-04 00:42:54 -060090 virtual pldm_pdr* getPdr() const = 0;
George Liue53193f2020-02-24 09:23:26 +080091
92 /** @brief Add a PDR record to a PDR repository
93 *
94 * @param[in] pdrEntry - PDR records entry(data, size, recordHandle)
95 *
96 * @return uint32_t - record handle assigned to PDR record
97 */
98 virtual RecordHandle addRecord(const PdrEntry& pdrEntry) = 0;
99
100 /** @brief Get the first PDR record from a PDR repository
101 *
102 * @param[in] pdrEntry - PDR records entry(data, size, nextRecordHandle)
103 *
104 * @return opaque pointer acting as PDR record handle, will be NULL if
105 * record was not found
106 */
107 virtual const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) = 0;
108
109 /** @brief Get the next PDR record from a PDR repository
110 *
111 * @param[in] currRecord - opaque pointer acting as a PDR record handle
112 * @param[in] pdrEntry - PDR records entry(data, size, nextRecordHandle)
113 *
114 * @return opaque pointer acting as PDR record handle, will be NULL if
115 * record was not found
116 */
117 virtual const pldm_pdr_record*
118 getNextRecord(const pldm_pdr_record* currRecord,
119 PdrEntry& pdrEntry) = 0;
120
121 /** @brief Get record handle of a PDR record
122 *
123 * @param[in] record - opaque pointer acting as a PDR record handle
124 *
125 * @return uint32_t - record handle assigned to PDR record; 0 if record is
126 * not found
127 */
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600128 virtual uint32_t getRecordHandle(const pldm_pdr_record* record) const = 0;
George Liue53193f2020-02-24 09:23:26 +0800129
130 /** @brief Get number of records in a PDR repository
131 *
132 * @return uint32_t - number of records
133 */
134 virtual uint32_t getRecordCount() = 0;
135
136 /** @brief Determine if records are empty in a PDR repository
137 *
138 * @return bool - true means empty and false means not empty
139 */
140 virtual bool empty() = 0;
141
142 protected:
143 pldm_pdr* repo;
144};
145
146/**
147 * @class Repo
148 *
149 * Wrapper class to handle the PDR APIs
150 *
151 * This class wraps operations used to handle PDR APIs.
152 */
153class Repo : public RepoInterface
154{
155 public:
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600156 Repo(pldm_pdr* repo) : RepoInterface(repo)
George Liue53193f2020-02-24 09:23:26 +0800157 {
George Liue53193f2020-02-24 09:23:26 +0800158 }
159
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600160 pldm_pdr* getPdr() const override;
George Liue53193f2020-02-24 09:23:26 +0800161
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600162 RecordHandle addRecord(const PdrEntry& pdrEntry) override;
George Liue53193f2020-02-24 09:23:26 +0800163
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600164 const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) override;
George Liue53193f2020-02-24 09:23:26 +0800165
166 const pldm_pdr_record* getNextRecord(const pldm_pdr_record* currRecord,
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600167 PdrEntry& pdrEntry) override;
George Liue53193f2020-02-24 09:23:26 +0800168
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600169 uint32_t getRecordHandle(const pldm_pdr_record* record) const override;
George Liue53193f2020-02-24 09:23:26 +0800170
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600171 uint32_t getRecordCount() override;
George Liue53193f2020-02-24 09:23:26 +0800172
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600173 bool empty() override;
George Liue53193f2020-02-24 09:23:26 +0800174};
175
176} // namespace pdr_utils
177} // namespace responder
178} // namespace pldm