blob: 6aef73d6331a247ebdd20d119913a1013c6377f8 [file] [log] [blame]
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05301
2#include "platform.hpp"
3
George Liua2870722020-02-11 11:09:30 +08004#include "pdr_state_effecter.hpp"
George Liu83409572019-12-24 18:42:54 +08005#include "utils.hpp"
6
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05307namespace pldm
8{
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05309namespace responder
10{
Sampa Misraa2fa0702019-05-31 01:28:55 -050011namespace platform
12{
13
Deepak Kodihallic682fe22020-03-04 00:42:54 -060014using InternalFailure =
15 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
16
George Liu1ec85d42020-02-12 16:05:32 +080017static const Json empty{};
18
George Liua2870722020-02-11 11:09:30 +080019void Handler::addDbusObjMaps(
20 uint16_t effecterId,
21 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj)
George Liu1ec85d42020-02-12 16:05:32 +080022{
23 dbusObjMaps.emplace(effecterId, dbusObj);
24}
25
George Liua2870722020-02-11 11:09:30 +080026const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
George Liu1ec85d42020-02-12 16:05:32 +080027 Handler::getDbusObjMaps(uint16_t effecterId) const
28{
29 return dbusObjMaps.at(effecterId);
30}
31
Deepak Kodihallic682fe22020-03-04 00:42:54 -060032void Handler::generate(const std::string& dir, Repo& repo)
33{
34 // A map of PDR type to a lambda that handles creation of that PDR type.
35 // The lambda essentially would parse the platform specific PDR JSONs to
36 // generate the PDR structures. This function iterates through the map to
37 // invoke all lambdas, so that all PDR types can be created.
George Liua2870722020-02-11 11:09:30 +080038
39 const std::map<Type, generatePDR> generateHandlers = {
40 {PLDM_STATE_EFFECTER_PDR,
41 [this](const auto& json, RepoInterface& repo) {
42 pdr_state_effecter::generateStateEffecterPDR<Handler>(json, *this,
43 repo);
44 }}};
Deepak Kodihallic682fe22020-03-04 00:42:54 -060045
46 Type pdrType{};
47 for (const auto& dirEntry : fs::directory_iterator(dir))
48 {
49 try
50 {
51 auto json = readJson(dirEntry.path().string());
52 if (!json.empty())
53 {
George Liu1ec85d42020-02-12 16:05:32 +080054 auto effecterPDRs = json.value("effecterPDRs", empty);
55 for (const auto& effecter : effecterPDRs)
56 {
57 pdrType = effecter.value("pdrType", 0);
George Liua2870722020-02-11 11:09:30 +080058 generateHandlers.at(pdrType)(effecter, repo);
George Liu1ec85d42020-02-12 16:05:32 +080059 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -060060 }
61 }
62 catch (const InternalFailure& e)
63 {
64 std::cerr << "PDR config directory does not exist or empty, TYPE= "
65 << pdrType << "PATH= " << dirEntry
66 << " ERROR=" << e.what() << "\n";
67 }
68 catch (const Json::exception& e)
69 {
70 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
71 << " ERROR=" << e.what() << "\n";
72 pldm::utils::reportError(
73 "xyz.openbmc_project.bmc.pldm.InternalFailure");
74 }
75 catch (const std::exception& e)
76 {
77 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
78 << " ERROR=" << e.what() << "\n";
79 pldm::utils::reportError(
80 "xyz.openbmc_project.bmc.pldm.InternalFailure");
81 }
82 }
83}
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053084
Deepak Kodihallibc669f12019-11-28 08:52:07 -060085Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053086{
87 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
88 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
89
90 if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
91 {
George Liufb8611d2019-12-06 10:14:15 +080092 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053093 }
94
95 uint32_t recordHandle{};
96 uint32_t dataTransferHandle{};
97 uint8_t transferOpFlag{};
98 uint16_t reqSizeBytes{};
99 uint16_t recordChangeNum{};
100
George Liufb8611d2019-12-06 10:14:15 +0800101 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
102 &dataTransferHandle, &transferOpFlag,
103 &reqSizeBytes, &recordChangeNum);
104 if (rc != PLDM_SUCCESS)
105 {
106 return CmdHandler::ccOnlyResponse(request, rc);
107 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530108
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530109 uint16_t respSizeBytes{};
110 uint8_t* recordData = nullptr;
111 try
112 {
George Liue53193f2020-02-24 09:23:26 +0800113 pdr_utils::PdrEntry e;
114 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
115 if (record == NULL)
116 {
117 return CmdHandler::ccOnlyResponse(
118 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
119 }
120
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530121 if (reqSizeBytes)
122 {
George Liue53193f2020-02-24 09:23:26 +0800123 respSizeBytes = e.size;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530124 if (respSizeBytes > reqSizeBytes)
125 {
126 respSizeBytes = reqSizeBytes;
127 }
George Liue53193f2020-02-24 09:23:26 +0800128 recordData = e.data;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530129 }
130 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
131 respSizeBytes,
132 0);
133 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli22b5a7d2020-03-17 23:28:41 -0500134 rc = encode_get_pdr_resp(
135 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
136 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800137 if (rc != PLDM_SUCCESS)
138 {
139 return ccOnlyResponse(request, rc);
140 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530141 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530142 catch (const std::exception& e)
143 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600144 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
145 << " ERROR=" << e.what() << "\n";
George Liufb8611d2019-12-06 10:14:15 +0800146 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530147 }
148 return response;
149}
150
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600151Response Handler::setStateEffecterStates(const pldm_msg* request,
152 size_t payloadLength)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500153{
154 Response response(
155 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
156 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
157 uint16_t effecterId;
158 uint8_t compEffecterCnt;
159 constexpr auto maxCompositeEffecterCnt = 8;
160 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
161 {0, 0});
162
163 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
164 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
165 sizeof(set_effecter_state_field)))
166 {
George Liufb8611d2019-12-06 10:14:15 +0800167 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500168 }
169
170 int rc = decode_set_state_effecter_states_req(request, payloadLength,
171 &effecterId, &compEffecterCnt,
172 stateField.data());
173
George Liufb8611d2019-12-06 10:14:15 +0800174 if (rc != PLDM_SUCCESS)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500175 {
George Liufb8611d2019-12-06 10:14:15 +0800176 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500177 }
178
George Liufb8611d2019-12-06 10:14:15 +0800179 stateField.resize(compEffecterCnt);
180 const pldm::utils::DBusHandler dBusIntf;
181 rc = setStateEffecterStatesHandler<pldm::utils::DBusHandler>(
182 dBusIntf, effecterId, stateField);
183 if (rc != PLDM_SUCCESS)
184 {
185 return CmdHandler::ccOnlyResponse(request, rc);
186 }
187
188 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
189 responsePtr);
190 if (rc != PLDM_SUCCESS)
191 {
192 return ccOnlyResponse(request, rc);
193 }
194
Sampa Misraa2fa0702019-05-31 01:28:55 -0500195 return response;
196}
197
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600198} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530199} // namespace responder
200} // namespace pldm