blob: 8317cf084cb673264d4c1bc791631a1d4c3aa2eb [file] [log] [blame]
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001#include "host_pdr_handler.hpp"
2
George Liu682ee182020-12-25 15:24:33 +08003#include "libpldm/fru.h"
4#ifdef OEM_IBM
5#include "libpldm/fru_oem_ibm.h"
6#endif
7
8#include "custom_dbus.hpp"
9
Pavithra Barithayae8beb892020-04-14 23:24:25 -050010#include <assert.h>
11
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050012#include <nlohmann/json.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060013#include <phosphor-logging/lg2.hpp>
sampmisr6decfc12021-03-02 11:07:36 +053014#include <sdeventplus/clock.hpp>
15#include <sdeventplus/exception.hpp>
16#include <sdeventplus/source/io.hpp>
17#include <sdeventplus/source/time.hpp>
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050018
George Liu6492f522020-06-16 10:34:05 +080019#include <fstream>
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050020
Riya Dixit49cfb132023-03-02 04:26:53 -060021PHOSPHOR_LOG2_USING;
22
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050023namespace pldm
24{
Brad Bishop5079ac42021-08-19 18:35:06 -040025using namespace pldm::responder::events;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -050026using namespace pldm::utils;
27using namespace sdbusplus::bus::match::rules;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050028using Json = nlohmann::json;
29namespace fs = std::filesystem;
George Liu682ee182020-12-25 15:24:33 +080030using namespace pldm::dbus;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050031constexpr auto fruJson = "host_frus.json";
32const Json emptyJson{};
33const std::vector<Json> emptyJsonList{};
34
Manojkiran Eda3ca40452021-10-04 22:51:37 +053035template <typename T>
36uint16_t extractTerminusHandle(std::vector<uint8_t>& pdr)
37{
38 T* var = nullptr;
39 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
40 {
41 var = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
42 }
43 else
44 {
45 var = (T*)(pdr.data());
46 }
47 if (var != nullptr)
48 {
49 return var->terminus_handle;
50 }
51 return TERMINUS_HANDLE;
52}
53
Tom Joseph74f27c72021-05-16 07:58:53 -070054HostPDRHandler::HostPDRHandler(
55 int mctp_fd, uint8_t mctp_eid, sdeventplus::Event& event, pldm_pdr* repo,
56 const std::string& eventsJsonsDir, pldm_entity_association_tree* entityTree,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093057 pldm_entity_association_tree* bmcEntityTree,
58 pldm::InstanceIdDb& instanceIdDb,
Tom Josephe5268cd2021-09-07 13:04:03 +053059 pldm::requester::Handler<pldm::requester::Request>* handler) :
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050060 mctp_fd(mctp_fd),
Pavithra Barithaya3aec9972020-12-14 01:55:44 -060061 mctp_eid(mctp_eid), event(event), repo(repo),
62 stateSensorHandler(eventsJsonsDir), entityTree(entityTree),
Andrew Jefferya330b2f2023-05-04 14:55:37 +093063 bmcEntityTree(bmcEntityTree), instanceIdDb(instanceIdDb), handler(handler)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050064{
George Liuacf2c8c2021-05-10 14:08:52 +080065 mergedHostParents = false;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050066 fs::path hostFruJson(fs::path(HOST_JSONS_DIR) / fruJson);
67 if (fs::exists(hostFruJson))
68 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -050069 // Note parent entities for entities sent down by the host firmware.
70 // This will enable a merge of entity associations.
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050071 try
72 {
73 std::ifstream jsonFile(hostFruJson);
74 auto data = Json::parse(jsonFile, nullptr, false);
75 if (data.is_discarded())
76 {
Riya Dixit49cfb132023-03-02 04:26:53 -060077 error("Parsing Host FRU json file failed");
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050078 }
79 else
80 {
81 auto entities = data.value("entities", emptyJsonList);
82 for (auto& entity : entities)
83 {
84 EntityType entityType = entity.value("entity_type", 0);
85 auto parent = entity.value("parent", emptyJson);
86 pldm_entity p{};
87 p.entity_type = parent.value("entity_type", 0);
88 p.entity_instance_num = parent.value("entity_instance", 0);
89 parents.emplace(entityType, std::move(p));
90 }
91 }
92 }
93 catch (const std::exception& e)
94 {
Riya Dixit49cfb132023-03-02 04:26:53 -060095 error("Parsing Host FRU json file failed, exception = {ERR_EXCEP}",
96 "ERR_EXCEP", e.what());
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050097 }
98 }
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -050099
Patrick Williams84b790c2022-07-22 19:26:56 -0500100 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500101 pldm::utils::DBusHandler::getBus(),
102 propertiesChanged("/xyz/openbmc_project/state/host0",
103 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -0500104 [this, repo, entityTree, bmcEntityTree](sdbusplus::message_t& msg) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500105 DbusChangedProps props{};
106 std::string intf;
107 msg.read(intf, props);
108 const auto itr = props.find("CurrentHostState");
109 if (itr != props.end())
110 {
111 PropertyValue value = itr->second;
112 auto propVal = std::get<std::string>(value);
113 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500114 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500115 // Delete all the remote terminus information
116 std::erase_if(tlPDRInfo, [](const auto& item) {
117 auto const& [key, value] = item;
118 return key != TERMINUS_HANDLE;
119 });
120 pldm_pdr_remove_remote_pdrs(repo);
121 pldm_entity_association_tree_destroy_root(entityTree);
122 pldm_entity_association_tree_copy_root(bmcEntityTree,
123 entityTree);
124 this->sensorMap.clear();
125 this->responseReceived = false;
George Liuacf2c8c2021-05-10 14:08:52 +0800126 this->mergedHostParents = false;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500127 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500128 }
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500129 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500130}
131
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500132void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500133{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500134 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500135 modifiedPDRRecordHandles.clear();
136
137 if (isHostPdrModified)
138 {
139 modifiedPDRRecordHandles = std::move(recordHandles);
140 }
141 else
142 {
143 pdrRecordHandles = std::move(recordHandles);
144 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500145
146 // Defer the actual fetch of PDRs from the host (by queuing the call on the
147 // main event loop). That way, we can respond to the platform event msg from
148 // the host firmware.
149 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
150 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
151 std::placeholders::_1));
152}
153
154void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
155{
Sampa Misrac0c79482021-06-02 08:01:54 -0500156 getHostPDR();
157}
158
159void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
160{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500161 pdrFetchEvent.reset();
162
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500163 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
164 PLDM_GET_PDR_REQ_BYTES);
165 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500166 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500167 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
168 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500169 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500170 recordHandle = modifiedPDRRecordHandles.front();
171 modifiedPDRRecordHandles.pop_front();
172 }
173 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
174 {
175 recordHandle = pdrRecordHandles.front();
176 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500177 }
178 else
179 {
180 recordHandle = nextRecordHandle;
181 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930182 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500183
Patrick Williams6da4f912023-05-10 07:50:53 -0500184 auto rc = encode_get_pdr_req(instanceId, recordHandle, 0,
185 PLDM_GET_FIRSTPART, UINT16_MAX, 0, request,
186 PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500187 if (rc != PLDM_SUCCESS)
188 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930189 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600190 error("Failed to encode_get_pdr_req, rc = {RC}", "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500191 return;
192 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500193
Sampa Misrac0c79482021-06-02 08:01:54 -0500194 rc = handler->registerRequest(
195 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
196 std::move(requestMsg),
197 std::move(std::bind_front(&HostPDRHandler::processHostPDRs, this)));
198 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500199 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600200 error("Failed to send the GetPDR request to Host");
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500201 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500202}
203
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600204int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
205 pdr::EventState state)
206{
207 auto rc = stateSensorHandler.eventAction(entry, state);
208 if (rc != PLDM_SUCCESS)
209 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600210 error("Failed to fetch and update D-bus property, rc = {RC}", "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600211 return rc;
212 }
213 return PLDM_SUCCESS;
214}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500215
216void HostPDRHandler::mergeEntityAssociations(const std::vector<uint8_t>& pdr)
217{
218 size_t numEntities{};
219 pldm_entity* entities = nullptr;
220 bool merged = false;
221 auto entityPdr = reinterpret_cast<pldm_pdr_entity_association*>(
222 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
223
224 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
225 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800226 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500227 {
George Liuacf2c8c2021-05-10 14:08:52 +0800228 pldm_entity_node* pNode = nullptr;
229 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500230 {
George Liuacf2c8c2021-05-10 14:08:52 +0800231 pNode = pldm_entity_association_tree_find_with_locality(
232 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500233 }
George Liuacf2c8c2021-05-10 14:08:52 +0800234 else
235 {
236 pNode = pldm_entity_association_tree_find_with_locality(
237 entityTree, &entities[0], true);
238 }
239 if (!pNode)
240 {
241 return;
242 }
243
George Liudf9a6d32020-12-22 16:27:16 +0800244 Entities entityAssoc;
245 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800246 for (size_t i = 1; i < numEntities; ++i)
247 {
George Liudf9a6d32020-12-22 16:27:16 +0800248 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800249 entityTree, &entities[i], entities[i].entity_instance_num,
250 pNode, entityPdr->association_type, true, true, 0xFFFF);
251 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800252 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800253 }
254
255 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800256 if (merged)
257 {
258 entityAssociations.push_back(entityAssoc);
259 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500260 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500261
262 if (merged)
263 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500264 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500265 pldm_entity_node* node = nullptr;
266 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
267 if (node == nullptr)
268 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600269 error("could not find referrence of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500270 }
271 else
272 {
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930273 int rc = pldm_entity_association_pdr_add_from_node_check(
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530274 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930275 if (rc)
276 {
277 error(
278 "Failed to add entity association PDR from node: {LIBPLDM_ERROR}",
279 "LIBPLDM_ERROR", rc);
280 }
Sampa Misra719ed392021-06-04 05:15:13 -0500281 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500282 }
Sampa Misra719ed392021-06-04 05:15:13 -0500283 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500284}
285
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500286void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
287 uint8_t eventDataFormat)
288{
289 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
290
291 // Extract from the PDR repo record handles of PDRs we want the host
292 // to pull up.
293 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
294 std::vector<uint8_t> numsOfChangeEntries(1);
295 std::vector<std::vector<ChangeEntry>> changeEntries(
296 numsOfChangeEntries.size());
297 for (auto pdrType : pdrTypes)
298 {
299 const pldm_pdr_record* record{};
300 do
301 {
302 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
303 nullptr, nullptr);
304 if (record && pldm_pdr_record_is_remote(record))
305 {
306 changeEntries[0].push_back(
307 pldm_pdr_get_record_handle(repo, record));
308 }
309 } while (record);
310 }
311 if (changeEntries.empty())
312 {
313 return;
314 }
315 numsOfChangeEntries[0] = changeEntries[0].size();
316
317 // Encode PLDM platform event msg to indicate a PDR repo change.
318 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
319 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
320 changeEntries[0].size() * sizeof(uint32_t);
321 std::vector<uint8_t> eventDataVec{};
322 eventDataVec.resize(maxSize);
323 auto eventData =
324 reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
325 eventDataVec.data());
326 size_t actualSize{};
327 auto firstEntry = changeEntries[0].data();
328 auto rc = encode_pldm_pdr_repository_chg_event_data(
329 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
330 &firstEntry, eventData, &actualSize, maxSize);
331 if (rc != PLDM_SUCCESS)
332 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600333 error("Failed to encode_pldm_pdr_repository_chg_event_data, rc = {RC}",
334 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500335 return;
336 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930337 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500338 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
339 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
340 actualSize);
341 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
342 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600343 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
344 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500345 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500346 if (rc != PLDM_SUCCESS)
347 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930348 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600349 error("Failed to encode_platform_event_message_req, rc = {RC}", "RC",
350 rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500351 return;
352 }
353
Patrick Williams6da4f912023-05-10 07:50:53 -0500354 auto platformEventMessageResponseHandler =
355 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700356 if (response == nullptr || !respMsgLen)
357 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600358 error(
359 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700360 return;
361 }
362
363 uint8_t completionCode{};
364 uint8_t status{};
365 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500366 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
367 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500368 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700369 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600370 error(
371 "Failed to decode_platform_event_message_resp: {RC}, cc = {CC}",
372 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Tom Joseph74f27c72021-05-16 07:58:53 -0700373 }
374 };
375
Sampa Misrac0c79482021-06-02 08:01:54 -0500376 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500377 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700378 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500379 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500380 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600381 error("Failed to send the PDR repository changed event request");
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500382 }
383}
384
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530385void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500386{
387 for (const auto& pdr : stateSensorPDRs)
388 {
389 SensorEntry sensorEntry{};
390 const auto& [terminusHandle, sensorID, sensorInfo] =
391 responder::pdr_utils::parseStateSensorPDR(pdr);
392 sensorEntry.sensorID = sensorID;
393 try
394 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530395 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500396 }
397 // If there is no mapping for terminusHandle assign the reserved TID
398 // value of 0xFF to indicate that.
399 catch (const std::out_of_range& e)
400 {
401 sensorEntry.terminusID = PLDM_TID_RESERVED;
402 }
403 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
404 }
405}
406
Sampa Misrac0c79482021-06-02 08:01:54 -0500407void HostPDRHandler::processHostPDRs(mctp_eid_t /*eid*/,
408 const pldm_msg* response,
409 size_t respMsgLen)
410{
411 static bool merged = false;
412 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800413 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500414 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600415 uint8_t tlEid = 0;
416 bool tlValid = true;
417 uint32_t rh = 0;
418 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530419 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600420 uint8_t tid = 0;
421
Sampa Misrac0c79482021-06-02 08:01:54 -0500422 uint8_t completionCode{};
423 uint32_t nextDataTransferHandle{};
424 uint8_t transferFlag{};
425 uint16_t respCount{};
426 uint8_t transferCRC{};
427 if (response == nullptr || !respMsgLen)
428 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600429 error("Failed to receive response for the GetPDR command");
Sampa Misrac0c79482021-06-02 08:01:54 -0500430 return;
431 }
432
433 auto rc = decode_get_pdr_resp(
434 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
435 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
436 nullptr, 0, &transferCRC);
437 std::vector<uint8_t> responsePDRMsg;
438 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
439 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500440 if (rc != PLDM_SUCCESS)
441 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600442 error("Failed to decode_get_pdr_resp, rc = {RC}", "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500443 return;
444 }
445 else
446 {
447 std::vector<uint8_t> pdr(respCount, 0);
448 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
449 &nextRecordHandle, &nextDataTransferHandle,
450 &transferFlag, &respCount, pdr.data(),
451 respCount, &transferCRC);
452 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
453 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600454 error("Failed to decode_get_pdr_resp: rc = {RC}, cc = {CC}", "RC",
455 rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -0500456 return;
457 }
458 else
459 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600460 // when nextRecordHandle is 0, we need the recordHandle of the last
461 // PDR and not 0-1.
462 if (!nextRecordHandle)
463 {
464 rh = nextRecordHandle;
465 }
466 else
467 {
468 rh = nextRecordHandle - 1;
469 }
470
Sampa Misrac0c79482021-06-02 08:01:54 -0500471 auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600472 if (!rh)
473 {
474 rh = pdrHdr->record_handle;
475 }
476
Sampa Misrac0c79482021-06-02 08:01:54 -0500477 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
478 {
479 this->mergeEntityAssociations(pdr);
480 merged = true;
481 }
482 else
483 {
484 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
485 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530486 pdrTerminusHandle =
487 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500488 auto tlpdr =
489 reinterpret_cast<const pldm_terminus_locator_pdr*>(
490 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600491
492 terminusHandle = tlpdr->terminus_handle;
493 tid = tlpdr->tid;
494 auto terminus_locator_type = tlpdr->terminus_locator_type;
495 if (terminus_locator_type ==
496 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
497 {
498 auto locatorValue = reinterpret_cast<
499 const pldm_terminus_locator_type_mctp_eid*>(
500 tlpdr->terminus_locator_value);
501 tlEid = static_cast<uint8_t>(locatorValue->eid);
502 }
503 if (tlpdr->validity == 0)
504 {
505 tlValid = false;
506 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500507 for (const auto& terminusMap : tlPDRInfo)
508 {
509 if ((terminusHandle == (terminusMap.first)) &&
510 (get<1>(terminusMap.second) == tlEid) &&
511 (get<2>(terminusMap.second) == tlpdr->validity))
512 {
513 // TL PDR already present with same validity don't
514 // add the PDR to the repo just return
515 return;
516 }
517 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530518 tlPDRInfo.insert_or_assign(
519 tlpdr->terminus_handle,
520 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500521 }
522 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
523 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530524 pdrTerminusHandle =
525 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500526 stateSensorPDRs.emplace_back(pdr);
527 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530528 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
529 {
530 pdrTerminusHandle =
531 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu682ee182020-12-25 15:24:33 +0800532 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530533 }
534 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
535 {
536 pdrTerminusHandle =
537 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
538 }
539 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
540 {
541 pdrTerminusHandle =
542 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
543 pdr);
544 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600545 // if the TLPDR is invalid update the repo accordingly
546 if (!tlValid)
547 {
548 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
549 tlValid);
550 }
551 else
552 {
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930553 rc = pldm_pdr_add_check(repo, pdr.data(), respCount, true,
554 pdrTerminusHandle, &rh);
555 if (rc)
556 {
557 // pldm_pdr_add() assert()ed on failure to add a PDR.
558 throw std::runtime_error("Failed to add PDR");
559 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600560 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500561 }
562 }
563 }
564 if (!nextRecordHandle)
565 {
George Liudf9a6d32020-12-22 16:27:16 +0800566 updateEntityAssociation(entityAssociations, entityTree, objPathMap);
567
Sampa Misrac0c79482021-06-02 08:01:54 -0500568 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530569 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800570 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600571 if (isHostUp())
572 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530573 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600574 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500575 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800576 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800577 entityAssociations.clear();
578
Sampa Misrac0c79482021-06-02 08:01:54 -0500579 if (merged)
580 {
581 merged = false;
582 deferredPDRRepoChgEvent =
583 std::make_unique<sdeventplus::source::Defer>(
584 event,
585 std::bind(
586 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
587 this, std::placeholders::_1));
588 }
589 }
590 else
591 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500592 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
593 {
594 isHostPdrModified = false;
595 }
596 else
597 {
598 deferredFetchPDREvent =
599 std::make_unique<sdeventplus::source::Defer>(
600 event,
601 std::bind(
602 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
603 this, nextRecordHandle, std::placeholders::_1));
604 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500605 }
606}
607
608void HostPDRHandler::_processPDRRepoChgEvent(
609 sdeventplus::source::EventBase& /*source */)
610{
611 deferredPDRRepoChgEvent.reset();
612 this->sendPDRRepositoryChgEvent(
613 std::move(std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION)),
614 FORMAT_IS_PDR_HANDLES);
615}
616
617void HostPDRHandler::_processFetchPDREvent(
618 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
619{
620 deferredFetchPDREvent.reset();
621 if (!this->pdrRecordHandles.empty())
622 {
623 nextRecordHandle = this->pdrRecordHandles.front();
624 this->pdrRecordHandles.pop_front();
625 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500626 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
627 {
628 nextRecordHandle = this->modifiedPDRRecordHandles.front();
629 this->modifiedPDRRecordHandles.pop_front();
630 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500631 this->getHostPDR(nextRecordHandle);
632}
633
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500634void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530635{
sampmisr6decfc12021-03-02 11:07:36 +0530636 responseReceived = false;
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930637 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500638 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
639 PLDM_GET_VERSION_REQ_BYTES);
640 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
641 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
642 PLDM_BASE, request);
643 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530644 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600645 error("GetPLDMVersion encode failure. PLDM error code = {RC}", "RC",
646 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930647 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530648 return;
649 }
650
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500651 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
652 const pldm_msg* response,
653 size_t respMsgLen) {
654 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530655 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600656 error(
657 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530658 return;
659 }
Riya Dixit49cfb132023-03-02 04:26:53 -0600660 info("Getting the response. PLDM RC = {RC}", "RC", lg2::hex,
661 static_cast<uint16_t>(response->payload[0]));
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500662 this->responseReceived = true;
663 getHostPDR();
sampmisr6decfc12021-03-02 11:07:36 +0530664 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500665 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
666 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
667 std::move(getPLDMVersionHandler));
668 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530669 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600670 error("Failed to discover Host state. Assuming Host as off");
sampmisr6decfc12021-03-02 11:07:36 +0530671 }
672}
673
674bool HostPDRHandler::isHostUp()
675{
676 return responseReceived;
677}
678
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530679void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600680{
681 for (const auto& stateSensorPDR : stateSensorPDRs)
682 {
683 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
684 stateSensorPDR.data());
685
686 if (!pdr)
687 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600688 error("Failed to get State sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600689 pldm::utils::reportError(
690 "xyz.openbmc_project.bmc.pldm.InternalFailure");
691 return;
692 }
693
694 uint16_t sensorId = pdr->sensor_id;
695
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530696 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600697 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530698 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600699 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530700 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600701 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530702 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600703 }
704
705 bitfield8_t sensorRearm;
706 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530707 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600708
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930709 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600710 std::vector<uint8_t> requestMsg(
711 sizeof(pldm_msg_hdr) +
712 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
713 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
714 auto rc = encode_get_state_sensor_readings_req(
715 instanceId, sensorId, sensorRearm, 0, request);
716
717 if (rc != PLDM_SUCCESS)
718 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930719 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600720 error(
721 "Failed to encode_get_state_sensor_readings_req, rc = {RC}",
722 "RC", rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600723 pldm::utils::reportError(
724 "xyz.openbmc_project.bmc.pldm.InternalFailure");
725 return;
726 }
727
Patrick Williams6da4f912023-05-10 07:50:53 -0500728 auto getStateSensorReadingRespHandler =
729 [=, this](mctp_eid_t /*eid*/, const pldm_msg* response,
730 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600731 if (response == nullptr || !respMsgLen)
732 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600733 error(
734 "Failed to receive response for getStateSensorReading command");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600735 return;
736 }
737 std::array<get_sensor_state_field, 8> stateField{};
738 uint8_t completionCode = 0;
739 uint8_t comp_sensor_count = 0;
740
741 auto rc = decode_get_state_sensor_readings_resp(
742 response, respMsgLen, &completionCode,
743 &comp_sensor_count, stateField.data());
744
745 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
746 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600747 error(
748 "Failed to decode_get_state_sensor_readings_resp, rc = {RC} cc = {CC}",
749 "RC", rc, "CC",
750 static_cast<unsigned>(completionCode));
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600751 pldm::utils::reportError(
752 "xyz.openbmc_project.bmc.pldm.InternalFailure");
753 }
754
755 uint8_t eventState;
756 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600757
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500758 for (uint8_t sensorOffset = 0;
759 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600760 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500761 eventState = stateField[sensorOffset].present_state;
762 previousEventState =
763 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600764
765 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
766 eventState,
767 previousEventState);
768
769 SensorEntry sensorEntry{tid, sensorId};
770
771 pldm::pdr::EntityInfo entityInfo{};
772 pldm::pdr::CompositeSensorStates
773 compositeSensorStates{};
774
775 try
776 {
777 std::tie(entityInfo, compositeSensorStates) =
778 lookupSensorInfo(sensorEntry);
779 }
780 catch (const std::out_of_range& e)
781 {
782 try
783 {
784 sensorEntry.terminusID = PLDM_TID_RESERVED;
785 std::tie(entityInfo, compositeSensorStates) =
786 lookupSensorInfo(sensorEntry);
787 }
788 catch (const std::out_of_range& e)
789 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600790 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600791 }
792 }
793
794 if (sensorOffset > compositeSensorStates.size())
795 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600796 error("Error Invalid data, Invalid sensor offset");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600797 return;
798 }
799
800 const auto& possibleStates =
801 compositeSensorStates[sensorOffset];
802 if (possibleStates.find(eventState) ==
803 possibleStates.end())
804 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600805 error("Error invalid_data, Invalid event state");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600806 return;
807 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500808 const auto& [containerId, entityType,
809 entityInstance] = entityInfo;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600810 pldm::responder::events::StateSensorEntry
811 stateSensorEntry{containerId, entityType,
812 entityInstance, sensorOffset};
813 handleStateSensorEvent(stateSensorEntry, eventState);
814 }
815 };
816
817 rc = handler->registerRequest(
818 mctp_eid, instanceId, PLDM_PLATFORM,
819 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg),
820 std::move(getStateSensorReadingRespHandler));
821
822 if (rc != PLDM_SUCCESS)
823 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600824 error(
825 "Failed to send request to get State sensor reading on Host");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600826 }
827 }
828 }
829 }
830}
George Liu682ee182020-12-25 15:24:33 +0800831
832void HostPDRHandler::getFRURecordTableMetadataByRemote(
833 const PDRList& fruRecordSetPDRs)
834{
835 auto instanceId = instanceIdDb.next(mctp_eid);
836 std::vector<uint8_t> requestMsg(
837 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
838
839 // GetFruRecordTableMetadata
840 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
841 auto rc = encode_get_fru_record_table_metadata_req(
842 instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
843 if (rc != PLDM_SUCCESS)
844 {
845 instanceIdDb.free(mctp_eid, instanceId);
846 lg2::error(
847 "Failed to encode_get_fru_record_table_metadata_req, rc = {RC}",
848 "RC", lg2::hex, rc);
849 return;
850 }
851
852 auto getFruRecordTableMetadataResponseHandler =
853 [this, fruRecordSetPDRs](mctp_eid_t /*eid*/, const pldm_msg* response,
854 size_t respMsgLen) {
855 if (response == nullptr || !respMsgLen)
856 {
857 lg2::error(
858 "Failed to receive response for the Get FRU Record Table Metadata");
859 return;
860 }
861
862 uint8_t cc = 0;
863 uint8_t fru_data_major_version, fru_data_minor_version;
864 uint32_t fru_table_maximum_size, fru_table_length;
865 uint16_t total_record_set_identifiers;
866 uint16_t total;
867 uint32_t checksum;
868
869 auto rc = decode_get_fru_record_table_metadata_resp(
870 response, respMsgLen, &cc, &fru_data_major_version,
871 &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
872 &total_record_set_identifiers, &total, &checksum);
873
874 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
875 {
876 lg2::error(
877 "Faile to decode get fru record table metadata resp, Message Error: {RC}, cc: {CC}",
878 "RC", lg2::hex, rc, "CC", cc);
879 return;
880 }
881
882 // pass total to getFRURecordTableByRemote
883 this->getFRURecordTableByRemote(fruRecordSetPDRs, total);
884 };
885
886 rc = handler->registerRequest(
887 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA,
888 std::move(requestMsg),
889 std::move(getFruRecordTableMetadataResponseHandler));
890 if (rc != PLDM_SUCCESS)
891 {
892 lg2::error("Failed to send the the Set State Effecter States request");
893 }
894
895 return;
896}
897
898void HostPDRHandler::getFRURecordTableByRemote(const PDRList& fruRecordSetPDRs,
899 uint16_t totalTableRecords)
900{
901 fruRecordData.clear();
902
903 if (!totalTableRecords)
904 {
905 lg2::error("Failed to get fru record table");
906 return;
907 }
908
909 auto instanceId = instanceIdDb.next(mctp_eid);
910 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
911 PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
912
913 // send the getFruRecordTable command
914 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
915 auto rc = encode_get_fru_record_table_req(
916 instanceId, 0, PLDM_GET_FIRSTPART, request,
917 requestMsg.size() - sizeof(pldm_msg_hdr));
918 if (rc != PLDM_SUCCESS)
919 {
920 instanceIdDb.free(mctp_eid, instanceId);
921 lg2::error("Failed to encode_get_fru_record_table_req, rc = {RC}", "RC",
922 lg2::hex, rc);
923 return;
924 }
925
926 auto getFruRecordTableResponseHandler =
927 [totalTableRecords, this, fruRecordSetPDRs](
928 mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
929 if (response == nullptr || !respMsgLen)
930 {
931 lg2::error(
932 "Failed to receive response for the Get FRU Record Table");
933 return;
934 }
935
936 uint8_t cc = 0;
937 uint32_t next_data_transfer_handle = 0;
938 uint8_t transfer_flag = 0;
939 size_t fru_record_table_length = 0;
940 std::vector<uint8_t> fru_record_table_data(respMsgLen -
941 sizeof(pldm_msg_hdr));
942 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
943 auto rc = decode_get_fru_record_table_resp(
944 responsePtr, respMsgLen - sizeof(pldm_msg_hdr), &cc,
945 &next_data_transfer_handle, &transfer_flag,
946 fru_record_table_data.data(), &fru_record_table_length);
947
948 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
949 {
950 lg2::error(
951 "Failed to decode get fru record table resp, Message Error: {RC}, cc: {CC}",
952 "RC", lg2::hex, rc, "CC", cc);
953 return;
954 }
955
956 fruRecordData = responder::pdr_utils::parseFruRecordTable(
957 fru_record_table_data.data(), fru_record_table_length);
958
959 if (totalTableRecords != fruRecordData.size())
960 {
961 fruRecordData.clear();
962
963 lg2::error("failed to parse fru recrod data format.");
964 return;
965 }
966
967 this->setFRUDataOnDBus(fruRecordSetPDRs, fruRecordData);
968 };
969
970 rc = handler->registerRequest(
971 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE,
972 std::move(requestMsg), std::move(getFruRecordTableResponseHandler));
973 if (rc != PLDM_SUCCESS)
974 {
975 lg2::error("Failed to send the the Set State Effecter States request");
976 }
977}
978
979std::optional<uint16_t> HostPDRHandler::getRSI(const PDRList& fruRecordSetPDRs,
980 const pldm_entity& entity)
981{
982 for (const auto& pdr : fruRecordSetPDRs)
983 {
984 auto fruPdr = reinterpret_cast<const pldm_pdr_fru_record_set*>(
985 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
986
987 if (fruPdr->entity_type == entity.entity_type &&
Sagar Srinivasebf8bb52023-10-06 01:15:55 -0500988 fruPdr->entity_instance == entity.entity_instance_num &&
989 fruPdr->container_id == entity.entity_container_id)
George Liu682ee182020-12-25 15:24:33 +0800990 {
991 return fruPdr->fru_rsi;
992 }
993 }
994
995 return std::nullopt;
996}
997
998void HostPDRHandler::setFRUDataOnDBus(
Patrick Williamsd310f822023-10-07 19:01:19 -0500999 [[maybe_unused]] const PDRList& fruRecordSetPDRs,
1000 [[maybe_unused]] const std::vector<
1001 responder::pdr_utils::FruRecordDataFormat>& fruRecordData)
George Liu682ee182020-12-25 15:24:33 +08001002{
Patrick Williamsd310f822023-10-07 19:01:19 -05001003#ifdef OEM_IBM
George Liu682ee182020-12-25 15:24:33 +08001004 for (const auto& entity : objPathMap)
1005 {
1006 pldm_entity node = pldm_entity_extract(entity.second);
1007 auto fruRSI = getRSI(fruRecordSetPDRs, node);
1008
1009 for (const auto& data : fruRecordData)
1010 {
1011 if (!fruRSI || *fruRSI != data.fruRSI)
1012 {
1013 continue;
1014 }
1015
1016 if (data.fruRecType == PLDM_FRU_RECORD_TYPE_OEM)
1017 {
1018 for (const auto& tlv : data.fruTLV)
1019 {
1020 if (tlv.fruFieldType ==
1021 PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE)
1022 {
1023 CustomDBus::getCustomDBus().setLocationCode(
1024 entity.first,
1025 std::string(reinterpret_cast<const char*>(
1026 tlv.fruFieldValue.data()),
1027 tlv.fruFieldLen));
1028 }
1029 }
1030 }
1031 }
1032 }
Patrick Williamsd310f822023-10-07 19:01:19 -05001033#endif
George Liu682ee182020-12-25 15:24:33 +08001034}
1035void HostPDRHandler::createDbusObjects(const PDRList& fruRecordSetPDRs)
1036{
1037 // TODO: Creating and Refreshing dbus hosted by remote PLDM entity Fru PDRs
1038
1039 getFRURecordTableMetadataByRemote(fruRecordSetPDRs);
1040}
1041
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001042} // namespace pldm