blob: 079c6dcac4fc5d8f25df373d6844c477aa8a10ce [file] [log] [blame]
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001#include "host_pdr_handler.hpp"
2
Andrew Jeffery4668f5c2024-01-15 14:59:17 +10303#include <libpldm/fru.h>
George Liu682ee182020-12-25 15:24:33 +08004#ifdef OEM_IBM
Andrew Jeffery21f128d2024-01-15 15:34:26 +10305#include <libpldm/oem/ibm/fru.h>
Sagar Srinivas3687e2b2023-04-10 05:08:28 -05006#endif
Kamalkumar Patel14107a12024-06-19 08:50:01 -05007#include "dbus/custom_dbus.hpp"
George Liu682ee182020-12-25 15:24:33 +08008
Deepak Kodihalli87514cc2020-04-16 09:08:38 -05009#include <nlohmann/json.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060010#include <phosphor-logging/lg2.hpp>
sampmisr6decfc12021-03-02 11:07:36 +053011#include <sdeventplus/clock.hpp>
12#include <sdeventplus/exception.hpp>
13#include <sdeventplus/source/io.hpp>
14#include <sdeventplus/source/time.hpp>
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050015
Pavithra Barithayab3b84b42024-08-23 11:43:57 +053016#include <cassert>
George Liu6492f522020-06-16 10:34:05 +080017#include <fstream>
George Liu96af8cb2021-07-31 15:23:45 +080018#include <type_traits>
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050019
Riya Dixit49cfb132023-03-02 04:26:53 -060020PHOSPHOR_LOG2_USING;
21
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050022namespace pldm
23{
Brad Bishop5079ac42021-08-19 18:35:06 -040024using namespace pldm::responder::events;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -050025using namespace pldm::utils;
26using namespace sdbusplus::bus::match::rules;
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050027using namespace pldm::responder::pdr_utils;
Kamalkumar Patel516122e2024-05-07 04:39:32 -050028using namespace pldm::hostbmc::utils;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050029using Json = nlohmann::json;
30namespace fs = std::filesystem;
George Liu682ee182020-12-25 15:24:33 +080031using namespace pldm::dbus;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050032const Json emptyJson{};
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050033
Manojkiran Eda3ca40452021-10-04 22:51:37 +053034template <typename T>
35uint16_t extractTerminusHandle(std::vector<uint8_t>& pdr)
36{
37 T* var = nullptr;
38 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
39 {
40 var = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
41 }
42 else
43 {
44 var = (T*)(pdr.data());
45 }
46 if (var != nullptr)
47 {
48 return var->terminus_handle;
49 }
50 return TERMINUS_HANDLE;
51}
52
George Liu96af8cb2021-07-31 15:23:45 +080053template <typename T>
54void updateContainerId(pldm_entity_association_tree* entityTree,
55 std::vector<uint8_t>& pdr)
56{
57 T* t = nullptr;
58 if (entityTree == nullptr)
59 {
60 return;
61 }
62 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
63 {
64 t = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
65 }
66 else
67 {
68 t = (T*)(pdr.data());
69 }
70 if (t == nullptr)
71 {
72 return;
73 }
74
75 pldm_entity entity{t->entity_type, t->entity_instance, t->container_id};
Patrick Williams16c2a0a2024-08-16 15:20:59 -040076 auto node = pldm_entity_association_tree_find_with_locality(
77 entityTree, &entity, true);
George Liu96af8cb2021-07-31 15:23:45 +080078 if (node)
79 {
80 pldm_entity e = pldm_entity_extract(node);
81 t->container_id = e.entity_container_id;
82 }
83}
84
Tom Joseph74f27c72021-05-16 07:58:53 -070085HostPDRHandler::HostPDRHandler(
Andrew Jeffery3dd444d2024-07-25 22:00:27 +093086 int /* mctp_fd */, uint8_t mctp_eid, sdeventplus::Event& event,
87 pldm_pdr* repo, const std::string& eventsJsonsDir,
88 pldm_entity_association_tree* entityTree,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093089 pldm_entity_association_tree* bmcEntityTree,
90 pldm::InstanceIdDb& instanceIdDb,
George Liua881c172021-06-21 18:28:11 +080091 pldm::requester::Handler<pldm::requester::Request>* handler) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040092 mctp_eid(mctp_eid), event(event), repo(repo),
93 stateSensorHandler(eventsJsonsDir), entityTree(entityTree),
94 instanceIdDb(instanceIdDb), handler(handler),
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -050095 entityMaps(parseEntityMap(ENTITY_MAP_JSON)), oemUtilsHandler(nullptr)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050096{
George Liuacf2c8c2021-05-10 14:08:52 +080097 mergedHostParents = false;
Patrick Williams84b790c2022-07-22 19:26:56 -050098 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -050099 pldm::utils::DBusHandler::getBus(),
100 propertiesChanged("/xyz/openbmc_project/state/host0",
101 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -0500102 [this, repo, entityTree, bmcEntityTree](sdbusplus::message_t& msg) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400103 DbusChangedProps props{};
104 std::string intf;
105 msg.read(intf, props);
106 const auto itr = props.find("CurrentHostState");
107 if (itr != props.end())
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500108 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400109 PropertyValue value = itr->second;
110 auto propVal = std::get<std::string>(value);
111 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
112 {
113 // Delete all the remote terminus information
114 std::erase_if(tlPDRInfo, [](const auto& item) {
115 const auto& [key, value] = item;
116 return key != TERMINUS_HANDLE;
117 });
Archana Kakanif9355372025-02-04 03:13:24 -0600118 // when the host is powered off, set the availability
119 // state of all the dbus objects to false
120 this->setPresenceFrus();
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400121 pldm_pdr_remove_remote_pdrs(repo);
122 pldm_entity_association_tree_destroy_root(entityTree);
123 pldm_entity_association_tree_copy_root(bmcEntityTree,
124 entityTree);
125 this->sensorMap.clear();
126 this->responseReceived = false;
127 this->mergedHostParents = false;
Archana Kakani50554252025-03-17 01:37:29 -0500128
129 // After a power off , the remote nodes will be deleted
130 // from the entity association tree, making the nodes point
131 // to junk values, so set them to nullptr
132 for (const auto& element : this->objPathMap)
133 {
134 this->objPathMap[element.first] = nullptr;
135 }
136 }
137 else if (propVal ==
138 "xyz.openbmc_project.State.Host.HostState.Running")
139 {
140 if (oemPlatformHandler)
141 {
142 oemPlatformHandler->handleBootTypesAtPowerOn();
143 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400144 }
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500145 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400146 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500147}
148
Archana Kakanif9355372025-02-04 03:13:24 -0600149void HostPDRHandler::setPresenceFrus()
150{
151 // iterate over all dbus objects
152 for (const auto& [path, entityId] : objPathMap)
153 {
154 CustomDBus::getCustomDBus().setAvailabilityState(path, false);
155 }
156}
157
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500158void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500159{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500160 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500161 modifiedPDRRecordHandles.clear();
162
163 if (isHostPdrModified)
164 {
165 modifiedPDRRecordHandles = std::move(recordHandles);
166 }
167 else
168 {
169 pdrRecordHandles = std::move(recordHandles);
170 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500171
172 // Defer the actual fetch of PDRs from the host (by queuing the call on the
173 // main event loop). That way, we can respond to the platform event msg from
174 // the host firmware.
175 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
176 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
177 std::placeholders::_1));
178}
179
180void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
181{
Sampa Misrac0c79482021-06-02 08:01:54 -0500182 getHostPDR();
183}
184
185void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
186{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500187 pdrFetchEvent.reset();
188
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400189 std::vector<uint8_t> requestMsg(
190 sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530191 auto request = new (requestMsg.data()) pldm_msg;
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500192 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500193 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
194 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500195 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500196 recordHandle = modifiedPDRRecordHandles.front();
197 modifiedPDRRecordHandles.pop_front();
198 }
199 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
200 {
201 recordHandle = pdrRecordHandles.front();
202 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500203 }
204 else
205 {
206 recordHandle = nextRecordHandle;
207 }
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000208 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500209
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400210 auto rc =
211 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
212 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500213 if (rc != PLDM_SUCCESS)
214 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930215 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500216 error("Failed to encode get pdr request, response code '{RC}'", "RC",
217 rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500218 return;
219 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500220
Sampa Misrac0c79482021-06-02 08:01:54 -0500221 rc = handler->registerRequest(
222 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
223 std::move(requestMsg),
Eric Yang70eca962025-05-11 01:48:15 +0800224 [this](mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen) {
225 this->processHostPDRs(eid, response, respMsgLen);
226 });
Sampa Misrac0c79482021-06-02 08:01:54 -0500227 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500228 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500229 error(
230 "Failed to send the getPDR request to remote terminus, response code '{RC}'",
231 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500232 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500233}
234
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600235int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
236 pdr::EventState state)
237{
238 auto rc = stateSensorHandler.eventAction(entry, state);
239 if (rc != PLDM_SUCCESS)
240 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500241 error("Failed to fetch and update D-bus property, response code '{RC}'",
242 "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600243 return rc;
244 }
245 return PLDM_SUCCESS;
246}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500247
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500248void HostPDRHandler::mergeEntityAssociations(
249 const std::vector<uint8_t>& pdr, [[maybe_unused]] const uint32_t& size,
250 [[maybe_unused]] const uint32_t& record_handle)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500251{
252 size_t numEntities{};
253 pldm_entity* entities = nullptr;
254 bool merged = false;
Pavithra Barithaya49575832025-01-29 16:27:30 +0530255 auto entityPdr = new (const_cast<uint8_t*>(pdr.data()) +
256 sizeof(pldm_pdr_hdr)) pldm_pdr_entity_association;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500257
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500258 if (oemPlatformHandler &&
259 oemPlatformHandler->checkRecordHandleInRange(record_handle))
260 {
261 // Adding the remote range PDRs to the repo before merging it
262 uint32_t handle = record_handle;
Andrew Jeffery5a945bd2024-08-01 13:15:36 +0000263 pldm_pdr_add(repo, pdr.data(), size, true, 0xFFFF, &handle);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500264 }
265
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500266 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
267 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800268 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500269 {
George Liuacf2c8c2021-05-10 14:08:52 +0800270 pldm_entity_node* pNode = nullptr;
271 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500272 {
George Liuacf2c8c2021-05-10 14:08:52 +0800273 pNode = pldm_entity_association_tree_find_with_locality(
274 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500275 }
George Liuacf2c8c2021-05-10 14:08:52 +0800276 else
277 {
278 pNode = pldm_entity_association_tree_find_with_locality(
279 entityTree, &entities[0], true);
280 }
281 if (!pNode)
282 {
283 return;
284 }
285
George Liudf9a6d32020-12-22 16:27:16 +0800286 Entities entityAssoc;
287 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800288 for (size_t i = 1; i < numEntities; ++i)
289 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500290 bool isUpdateContainerId = true;
291 if (oemPlatformHandler)
292 {
293 isUpdateContainerId =
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600294 checkIfLogicalBitSet(entities[i].entity_container_id);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500295 }
George Liudf9a6d32020-12-22 16:27:16 +0800296 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800297 entityTree, &entities[i], entities[i].entity_instance_num,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500298 pNode, entityPdr->association_type, true, isUpdateContainerId,
299 0xFFFF);
300 if (!node)
301 {
302 continue;
303 }
George Liuacf2c8c2021-05-10 14:08:52 +0800304 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800305 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800306 }
307
308 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800309 if (merged)
310 {
311 entityAssociations.push_back(entityAssoc);
312 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500313 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500314
315 if (merged)
316 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500317 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500318 pldm_entity_node* node = nullptr;
319 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
320 if (node == nullptr)
321 {
Manojkiran Eda2576aec2024-06-17 12:05:17 +0530322 error("Failed to find reference of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500323 }
324 else
325 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500326 int rc = 0;
327 if (oemPlatformHandler)
328 {
329 auto record = oemPlatformHandler->fetchLastBMCRecord(repo);
330
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400331 uint32_t record_handle =
332 pldm_pdr_get_record_handle(repo, record);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500333
334 rc =
335 pldm_entity_association_pdr_add_from_node_with_record_handle(
336 node, repo, &entities, numEntities, true,
337 TERMINUS_HANDLE, (record_handle + 1));
338 }
339 else
340 {
Andrew Jeffery7761bd22024-08-01 13:15:36 +0000341 rc = pldm_entity_association_pdr_add_from_node(
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500342 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
343 }
344
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930345 if (rc)
346 {
347 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500348 "Failed to add entity association PDR from node, response code '{RC}'",
349 "RC", rc);
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930350 }
Sampa Misra719ed392021-06-04 05:15:13 -0500351 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500352 }
Sampa Misra719ed392021-06-04 05:15:13 -0500353 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500354}
355
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500356void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
357 uint8_t eventDataFormat)
358{
359 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
360
361 // Extract from the PDR repo record handles of PDRs we want the host
362 // to pull up.
363 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
364 std::vector<uint8_t> numsOfChangeEntries(1);
365 std::vector<std::vector<ChangeEntry>> changeEntries(
366 numsOfChangeEntries.size());
367 for (auto pdrType : pdrTypes)
368 {
369 const pldm_pdr_record* record{};
370 do
371 {
372 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
373 nullptr, nullptr);
374 if (record && pldm_pdr_record_is_remote(record))
375 {
376 changeEntries[0].push_back(
377 pldm_pdr_get_record_handle(repo, record));
378 }
379 } while (record);
380 }
381 if (changeEntries.empty())
382 {
383 return;
384 }
385 numsOfChangeEntries[0] = changeEntries[0].size();
386
387 // Encode PLDM platform event msg to indicate a PDR repo change.
388 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
389 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
390 changeEntries[0].size() * sizeof(uint32_t);
391 std::vector<uint8_t> eventDataVec{};
392 eventDataVec.resize(maxSize);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530393 auto eventData = new (eventDataVec.data())
394 pldm_pdr_repository_chg_event_data;
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500395 size_t actualSize{};
396 auto firstEntry = changeEntries[0].data();
397 auto rc = encode_pldm_pdr_repository_chg_event_data(
398 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
399 &firstEntry, eventData, &actualSize, maxSize);
400 if (rc != PLDM_SUCCESS)
401 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500402 error(
403 "Failed to encode pldm pdr repository change event data, response code '{RC}'",
404 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500405 return;
406 }
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000407 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400408 std::vector<uint8_t> requestMsg(
409 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
410 actualSize);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530411 auto request = new (requestMsg.data()) pldm_msg;
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500412 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600413 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
414 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500415 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500416 if (rc != PLDM_SUCCESS)
417 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930418 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500419 error(
420 "Failed to encode platform event message request, response code '{RC}'",
421 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500422 return;
423 }
424
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400425 auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/,
426 const pldm_msg* response,
427 size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700428 if (response == nullptr || !respMsgLen)
429 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600430 error(
431 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700432 return;
433 }
434
435 uint8_t completionCode{};
436 uint8_t status{};
437 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500438 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
439 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500440 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700441 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600442 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500443 "Failed to decode platform event message response, response code '{RC}' and completion code '{CC}'",
444 "RC", rc, "CC", completionCode);
Tom Joseph74f27c72021-05-16 07:58:53 -0700445 }
446 };
447
Sampa Misrac0c79482021-06-02 08:01:54 -0500448 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500449 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700450 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500451 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500452 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500453 error(
454 "Failed to send the PDR repository changed event request, response code '{RC}'",
455 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500456 }
457}
458
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530459void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500460{
461 for (const auto& pdr : stateSensorPDRs)
462 {
463 SensorEntry sensorEntry{};
464 const auto& [terminusHandle, sensorID, sensorInfo] =
465 responder::pdr_utils::parseStateSensorPDR(pdr);
466 sensorEntry.sensorID = sensorID;
467 try
468 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530469 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500470 }
471 // If there is no mapping for terminusHandle assign the reserved TID
472 // value of 0xFF to indicate that.
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500473 catch (const std::out_of_range&)
Sampa Misra868c8792020-05-26 03:12:13 -0500474 {
475 sensorEntry.terminusID = PLDM_TID_RESERVED;
476 }
477 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
478 }
479}
480
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400481void HostPDRHandler::processHostPDRs(
482 mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen)
Sampa Misrac0c79482021-06-02 08:01:54 -0500483{
484 static bool merged = false;
485 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800486 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500487 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600488 uint8_t tlEid = 0;
489 bool tlValid = true;
490 uint32_t rh = 0;
491 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530492 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600493 uint8_t tid = 0;
494
Sampa Misrac0c79482021-06-02 08:01:54 -0500495 uint8_t completionCode{};
496 uint32_t nextDataTransferHandle{};
497 uint8_t transferFlag{};
498 uint16_t respCount{};
499 uint8_t transferCRC{};
500 if (response == nullptr || !respMsgLen)
501 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600502 error("Failed to receive response for the GetPDR command");
Riya Dixit478e71d2024-06-21 14:10:14 -0500503 pldm::utils::reportError(
504 "xyz.openbmc_project.PLDM.Error.GetPDR.PDRExchangeFailure");
Sampa Misrac0c79482021-06-02 08:01:54 -0500505 return;
506 }
507
508 auto rc = decode_get_pdr_resp(
509 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
510 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
511 nullptr, 0, &transferCRC);
512 std::vector<uint8_t> responsePDRMsg;
513 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
514 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500515 if (rc != PLDM_SUCCESS)
516 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500517 error(
518 "Failed to decode getPDR response for next record handle '{NEXT_RECORD_HANDLE}', response code '{RC}'",
519 "NEXT_RECORD_HANDLE", nextRecordHandle, "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500520 return;
521 }
522 else
523 {
524 std::vector<uint8_t> pdr(respCount, 0);
525 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
526 &nextRecordHandle, &nextDataTransferHandle,
527 &transferFlag, &respCount, pdr.data(),
528 respCount, &transferCRC);
529 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
530 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500531 error(
532 "Failed to decode getPDR response for next record handle '{NEXT_RECORD_HANDLE}', next data transfer handle '{DATA_TRANSFER_HANDLE}' and transfer flag '{FLAG}', response code '{RC}' and completion code '{CC}'",
533 "NEXT_RECORD_HANDLE", nextRecordHandle, "DATA_TRANSFER_HANDLE",
534 nextDataTransferHandle, "FLAG", transferFlag, "RC", rc, "CC",
535 completionCode);
Sampa Misrac0c79482021-06-02 08:01:54 -0500536 return;
537 }
538 else
539 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600540 // when nextRecordHandle is 0, we need the recordHandle of the last
541 // PDR and not 0-1.
542 if (!nextRecordHandle)
543 {
544 rh = nextRecordHandle;
545 }
546 else
547 {
548 rh = nextRecordHandle - 1;
549 }
550
Pavithra Barithaya49575832025-01-29 16:27:30 +0530551 auto pdrHdr = new (pdr.data()) pldm_pdr_hdr;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600552 if (!rh)
553 {
554 rh = pdrHdr->record_handle;
555 }
556
Sampa Misrac0c79482021-06-02 08:01:54 -0500557 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
558 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500559 this->mergeEntityAssociations(pdr, respCount, rh);
Sampa Misrac0c79482021-06-02 08:01:54 -0500560 merged = true;
561 }
562 else
563 {
564 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
565 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530566 pdrTerminusHandle =
567 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500568 auto tlpdr =
569 reinterpret_cast<const pldm_terminus_locator_pdr*>(
570 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600571
572 terminusHandle = tlpdr->terminus_handle;
573 tid = tlpdr->tid;
574 auto terminus_locator_type = tlpdr->terminus_locator_type;
575 if (terminus_locator_type ==
576 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
577 {
578 auto locatorValue = reinterpret_cast<
579 const pldm_terminus_locator_type_mctp_eid*>(
580 tlpdr->terminus_locator_value);
581 tlEid = static_cast<uint8_t>(locatorValue->eid);
582 }
583 if (tlpdr->validity == 0)
584 {
585 tlValid = false;
586 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500587 for (const auto& terminusMap : tlPDRInfo)
588 {
589 if ((terminusHandle == (terminusMap.first)) &&
590 (get<1>(terminusMap.second) == tlEid) &&
591 (get<2>(terminusMap.second) == tlpdr->validity))
592 {
593 // TL PDR already present with same validity don't
594 // add the PDR to the repo just return
595 return;
596 }
597 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530598 tlPDRInfo.insert_or_assign(
599 tlpdr->terminus_handle,
600 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500601 }
602 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
603 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530604 pdrTerminusHandle =
605 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800606 updateContainerId<pldm_state_sensor_pdr>(entityTree, pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500607 stateSensorPDRs.emplace_back(pdr);
608 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530609 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
610 {
611 pdrTerminusHandle =
612 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800613 updateContainerId<pldm_pdr_fru_record_set>(entityTree, pdr);
George Liu682ee182020-12-25 15:24:33 +0800614 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530615 }
616 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
617 {
618 pdrTerminusHandle =
619 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800620 updateContainerId<pldm_state_effecter_pdr>(entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530621 }
622 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
623 {
624 pdrTerminusHandle =
625 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
626 pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800627 updateContainerId<pldm_numeric_effecter_value_pdr>(
628 entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530629 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600630 // if the TLPDR is invalid update the repo accordingly
631 if (!tlValid)
632 {
633 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
634 tlValid);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500635
636 if (!isHostUp())
637 {
638 // The terminus PDR becomes invalid when the terminus
639 // itself is down. We don't need to do PDR exchange in
640 // that case, so setting the next record handle to 0.
641 nextRecordHandle = 0;
642 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600643 }
644 else
645 {
Andrew Jeffery5a945bd2024-08-01 13:15:36 +0000646 rc = pldm_pdr_add(repo, pdr.data(), respCount, true,
647 pdrTerminusHandle, &rh);
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930648 if (rc)
649 {
650 // pldm_pdr_add() assert()ed on failure to add a PDR.
651 throw std::runtime_error("Failed to add PDR");
652 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600653 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500654 }
655 }
656 }
657 if (!nextRecordHandle)
658 {
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500659 updateEntityAssociation(entityAssociations, entityTree, objPathMap,
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500660 entityMaps, oemPlatformHandler);
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -0500661 if (oemUtilsHandler)
662 {
663 oemUtilsHandler->setCoreCount(entityAssociations, entityMaps);
664 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500665 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530666 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800667 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600668 if (isHostUp())
669 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530670 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600671 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500672 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800673 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800674 entityAssociations.clear();
675
Sampa Misrac0c79482021-06-02 08:01:54 -0500676 if (merged)
677 {
678 merged = false;
679 deferredPDRRepoChgEvent =
680 std::make_unique<sdeventplus::source::Defer>(
681 event,
682 std::bind(
683 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
684 this, std::placeholders::_1));
685 }
686 }
687 else
688 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500689 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
690 {
691 isHostPdrModified = false;
692 }
693 else
694 {
695 deferredFetchPDREvent =
696 std::make_unique<sdeventplus::source::Defer>(
697 event,
698 std::bind(
699 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
700 this, nextRecordHandle, std::placeholders::_1));
701 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500702 }
703}
704
705void HostPDRHandler::_processPDRRepoChgEvent(
706 sdeventplus::source::EventBase& /*source */)
707{
708 deferredPDRRepoChgEvent.reset();
709 this->sendPDRRepositoryChgEvent(
Andrew Jefferyc14fb4b2024-07-25 22:13:09 +0930710 std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION),
Sampa Misrac0c79482021-06-02 08:01:54 -0500711 FORMAT_IS_PDR_HANDLES);
712}
713
714void HostPDRHandler::_processFetchPDREvent(
715 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
716{
717 deferredFetchPDREvent.reset();
718 if (!this->pdrRecordHandles.empty())
719 {
720 nextRecordHandle = this->pdrRecordHandles.front();
721 this->pdrRecordHandles.pop_front();
722 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500723 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
724 {
725 nextRecordHandle = this->modifiedPDRRecordHandles.front();
726 this->modifiedPDRRecordHandles.pop_front();
727 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500728 this->getHostPDR(nextRecordHandle);
729}
730
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500731void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530732{
sampmisr6decfc12021-03-02 11:07:36 +0530733 responseReceived = false;
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000734 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400735 std::vector<uint8_t> requestMsg(
736 sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530737 auto request = new (requestMsg.data()) pldm_msg;
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500738 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
739 PLDM_BASE, request);
740 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530741 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500742 error("Failed to encode GetPLDMVersion, response code {RC}", "RC",
Riya Dixit49cfb132023-03-02 04:26:53 -0600743 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930744 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530745 return;
746 }
747
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500748 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
749 const pldm_msg* response,
750 size_t respMsgLen) {
751 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530752 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600753 error(
754 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530755 return;
756 }
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500757 info("Getting the response code '{RC}'", "RC", lg2::hex,
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500758 response->payload[0]);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500759 this->responseReceived = true;
sampmisr6decfc12021-03-02 11:07:36 +0530760 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500761 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
762 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
763 std::move(getPLDMVersionHandler));
764 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530765 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500766 error(
767 "Failed to discover remote terminus state. Assuming remote terminus as off");
sampmisr6decfc12021-03-02 11:07:36 +0530768 }
769}
770
771bool HostPDRHandler::isHostUp()
772{
773 return responseReceived;
774}
775
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530776void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600777{
778 for (const auto& stateSensorPDR : stateSensorPDRs)
779 {
780 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
781 stateSensorPDR.data());
782
783 if (!pdr)
784 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500785 error("Failed to get state sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600786 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530787 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600788 return;
789 }
790
791 uint16_t sensorId = pdr->sensor_id;
792
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530793 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600794 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530795 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600796 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530797 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600798 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530799 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600800 }
801
802 bitfield8_t sensorRearm;
803 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530804 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600805
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000806 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600807 std::vector<uint8_t> requestMsg(
808 sizeof(pldm_msg_hdr) +
809 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530810 auto request = new (requestMsg.data()) pldm_msg;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600811 auto rc = encode_get_state_sensor_readings_req(
812 instanceId, sensorId, sensorRearm, 0, request);
813
814 if (rc != PLDM_SUCCESS)
815 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930816 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600817 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500818 "Failed to encode get state sensor readings request for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
819 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
820 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600821 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530822 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600823 return;
824 }
825
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400826 auto getStateSensorReadingRespHandler = [=, this](
827 mctp_eid_t /*eid*/,
828 const pldm_msg*
829 response,
830 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600831 if (response == nullptr || !respMsgLen)
832 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600833 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500834 "Failed to receive response for get state sensor reading command for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}'",
835 "SENSOR_ID", sensorId, "INSTANCE", instanceId);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600836 return;
837 }
838 std::array<get_sensor_state_field, 8> stateField{};
839 uint8_t completionCode = 0;
840 uint8_t comp_sensor_count = 0;
841
842 auto rc = decode_get_state_sensor_readings_resp(
843 response, respMsgLen, &completionCode,
844 &comp_sensor_count, stateField.data());
845
846 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
847 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600848 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500849 "Failed to decode get state sensor readings response for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code'{RC}' and completion code '{CC}'",
850 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
851 rc, "CC", completionCode);
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530852 pldm::utils::reportError(
853 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600854 }
855
856 uint8_t eventState;
857 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600858
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500859 for (uint8_t sensorOffset = 0;
860 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600861 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500862 eventState = stateField[sensorOffset].present_state;
863 previousEventState =
864 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600865
866 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
867 eventState,
868 previousEventState);
869
870 SensorEntry sensorEntry{tid, sensorId};
871
872 pldm::pdr::EntityInfo entityInfo{};
873 pldm::pdr::CompositeSensorStates
874 compositeSensorStates{};
Sagar Srinivase3607a32024-02-16 03:50:53 -0600875 std::vector<pldm::pdr::StateSetId> stateSetIds{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600876
877 try
878 {
Sagar Srinivase3607a32024-02-16 03:50:53 -0600879 std::tie(entityInfo, compositeSensorStates,
880 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600881 lookupSensorInfo(sensorEntry);
882 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500883 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600884 {
885 try
886 {
887 sensorEntry.terminusID = PLDM_TID_RESERVED;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600888 std::tie(entityInfo, compositeSensorStates,
889 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600890 lookupSensorInfo(sensorEntry);
891 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500892 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600893 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600894 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600895 }
896 }
897
Manojkiran Eda07a07e22024-04-24 19:15:10 +0530898 if ((compositeSensorStates.size() > 1) &&
899 (sensorOffset > (compositeSensorStates.size() - 1)))
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600900 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500901 error(
902 "Error Invalid data, Invalid sensor offset '{SENSOR_OFFSET}'",
903 "SENSOR_OFFSET", sensorOffset);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600904 return;
905 }
906
907 const auto& possibleStates =
908 compositeSensorStates[sensorOffset];
909 if (possibleStates.find(eventState) ==
910 possibleStates.end())
911 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500912 error(
913 "Error invalid_data, Invalid event state '{STATE}'",
914 "STATE", eventState);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600915 return;
916 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400917 const auto& [containerId, entityType, entityInstance] =
918 entityInfo;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600919 auto stateSetId = stateSetIds[sensorOffset];
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600920 pldm::responder::events::StateSensorEntry
Manojkiran Edafa084702024-05-27 10:20:30 +0530921 stateSensorEntry{containerId, entityType,
Sagar Srinivase3607a32024-02-16 03:50:53 -0600922 entityInstance, sensorOffset,
Manojkiran Edafa084702024-05-27 10:20:30 +0530923 stateSetId, false};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600924 handleStateSensorEvent(stateSensorEntry, eventState);
925 }
926 };
927
928 rc = handler->registerRequest(
929 mctp_eid, instanceId, PLDM_PLATFORM,
930 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg),
931 std::move(getStateSensorReadingRespHandler));
932
933 if (rc != PLDM_SUCCESS)
934 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600935 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500936 "Failed to send request to get state sensor reading on remote terminus for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
937 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
938 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600939 }
940 }
941 }
942 }
943}
George Liu682ee182020-12-25 15:24:33 +0800944
945void HostPDRHandler::getFRURecordTableMetadataByRemote(
946 const PDRList& fruRecordSetPDRs)
947{
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000948 auto instanceId = instanceIdDb.next(mctp_eid);
George Liu682ee182020-12-25 15:24:33 +0800949 std::vector<uint8_t> requestMsg(
950 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
951
952 // GetFruRecordTableMetadata
Pavithra Barithaya49575832025-01-29 16:27:30 +0530953 auto request = new (requestMsg.data()) pldm_msg;
George Liu682ee182020-12-25 15:24:33 +0800954 auto rc = encode_get_fru_record_table_metadata_req(
955 instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
956 if (rc != PLDM_SUCCESS)
957 {
958 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500959 error(
960 "Failed to encode get fru record table metadata request, response code '{RC}'",
George Liu682ee182020-12-25 15:24:33 +0800961 "RC", lg2::hex, rc);
962 return;
963 }
964
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400965 auto getFruRecordTableMetadataResponseHandler = [this, fruRecordSetPDRs](
966 mctp_eid_t /*eid*/,
967 const pldm_msg*
968 response,
969 size_t respMsgLen) {
George Liu682ee182020-12-25 15:24:33 +0800970 if (response == nullptr || !respMsgLen)
971 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500972 error(
973 "Failed to receive response for the get fru record table metadata");
George Liu682ee182020-12-25 15:24:33 +0800974 return;
975 }
976
977 uint8_t cc = 0;
978 uint8_t fru_data_major_version, fru_data_minor_version;
979 uint32_t fru_table_maximum_size, fru_table_length;
980 uint16_t total_record_set_identifiers;
981 uint16_t total;
982 uint32_t checksum;
983
984 auto rc = decode_get_fru_record_table_metadata_resp(
985 response, respMsgLen, &cc, &fru_data_major_version,
986 &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
987 &total_record_set_identifiers, &total, &checksum);
988
989 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
990 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500991 error(
992 "Failed to decode get fru record table metadata response, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +0800993 "RC", lg2::hex, rc, "CC", cc);
994 return;
995 }
996
997 // pass total to getFRURecordTableByRemote
998 this->getFRURecordTableByRemote(fruRecordSetPDRs, total);
999 };
1000
1001 rc = handler->registerRequest(
1002 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA,
1003 std::move(requestMsg),
1004 std::move(getFruRecordTableMetadataResponseHandler));
1005 if (rc != PLDM_SUCCESS)
1006 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001007 error(
1008 "Failed to send the the set state effecter states request, response code '{RC}'",
1009 "RC", rc);
George Liu682ee182020-12-25 15:24:33 +08001010 }
1011
1012 return;
1013}
1014
1015void HostPDRHandler::getFRURecordTableByRemote(const PDRList& fruRecordSetPDRs,
1016 uint16_t totalTableRecords)
1017{
1018 fruRecordData.clear();
1019
1020 if (!totalTableRecords)
1021 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001022 error("Failed to get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001023 return;
1024 }
1025
ManojKiran Eda22bcb072025-07-11 23:49:43 +00001026 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001027 std::vector<uint8_t> requestMsg(
1028 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
George Liu682ee182020-12-25 15:24:33 +08001029
1030 // send the getFruRecordTable command
Pavithra Barithaya49575832025-01-29 16:27:30 +05301031 auto request = new (requestMsg.data()) pldm_msg;
George Liu682ee182020-12-25 15:24:33 +08001032 auto rc = encode_get_fru_record_table_req(
1033 instanceId, 0, PLDM_GET_FIRSTPART, request,
1034 requestMsg.size() - sizeof(pldm_msg_hdr));
1035 if (rc != PLDM_SUCCESS)
1036 {
1037 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001038 error(
1039 "Failed to encode get fru record table request, response code '{RC}'",
1040 "RC", lg2::hex, rc);
George Liu682ee182020-12-25 15:24:33 +08001041 return;
1042 }
1043
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001044 auto getFruRecordTableResponseHandler = [totalTableRecords, this,
1045 fruRecordSetPDRs](
1046 mctp_eid_t /*eid*/,
1047 const pldm_msg* response,
1048 size_t respMsgLen) {
George Liu682ee182020-12-25 15:24:33 +08001049 if (response == nullptr || !respMsgLen)
1050 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001051 error("Failed to receive response for the get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001052 return;
1053 }
1054
1055 uint8_t cc = 0;
1056 uint32_t next_data_transfer_handle = 0;
1057 uint8_t transfer_flag = 0;
1058 size_t fru_record_table_length = 0;
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001059 std::vector<uint8_t> fru_record_table_data(
1060 respMsgLen - sizeof(pldm_msg_hdr));
George Liu682ee182020-12-25 15:24:33 +08001061 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
1062 auto rc = decode_get_fru_record_table_resp(
Manojkiran Eda33a9cd02024-01-22 11:06:59 +05301063 responsePtr, respMsgLen, &cc, &next_data_transfer_handle,
1064 &transfer_flag, fru_record_table_data.data(),
1065 &fru_record_table_length);
George Liu682ee182020-12-25 15:24:33 +08001066
1067 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
1068 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001069 error(
1070 "Failed to decode get fru record table resp, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +08001071 "RC", lg2::hex, rc, "CC", cc);
1072 return;
1073 }
1074
1075 fruRecordData = responder::pdr_utils::parseFruRecordTable(
1076 fru_record_table_data.data(), fru_record_table_length);
1077
1078 if (totalTableRecords != fruRecordData.size())
1079 {
1080 fruRecordData.clear();
1081
Manojkiran Eda2576aec2024-06-17 12:05:17 +05301082 error("Failed to parse fru record data format.");
George Liu682ee182020-12-25 15:24:33 +08001083 return;
1084 }
1085
1086 this->setFRUDataOnDBus(fruRecordSetPDRs, fruRecordData);
1087 };
1088
1089 rc = handler->registerRequest(
1090 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE,
1091 std::move(requestMsg), std::move(getFruRecordTableResponseHandler));
1092 if (rc != PLDM_SUCCESS)
1093 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001094 error("Failed to send the the set state effecter states request");
George Liu682ee182020-12-25 15:24:33 +08001095 }
1096}
1097
1098std::optional<uint16_t> HostPDRHandler::getRSI(const PDRList& fruRecordSetPDRs,
1099 const pldm_entity& entity)
1100{
1101 for (const auto& pdr : fruRecordSetPDRs)
1102 {
1103 auto fruPdr = reinterpret_cast<const pldm_pdr_fru_record_set*>(
1104 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
1105
1106 if (fruPdr->entity_type == entity.entity_type &&
Sagar Srinivasebf8bb52023-10-06 01:15:55 -05001107 fruPdr->entity_instance == entity.entity_instance_num &&
1108 fruPdr->container_id == entity.entity_container_id)
George Liu682ee182020-12-25 15:24:33 +08001109 {
1110 return fruPdr->fru_rsi;
1111 }
1112 }
1113
1114 return std::nullopt;
1115}
1116
1117void HostPDRHandler::setFRUDataOnDBus(
Patrick Williamsd310f822023-10-07 19:01:19 -05001118 [[maybe_unused]] const PDRList& fruRecordSetPDRs,
1119 [[maybe_unused]] const std::vector<
1120 responder::pdr_utils::FruRecordDataFormat>& fruRecordData)
George Liu682ee182020-12-25 15:24:33 +08001121{
Patrick Williamsd310f822023-10-07 19:01:19 -05001122#ifdef OEM_IBM
George Liu682ee182020-12-25 15:24:33 +08001123 for (const auto& entity : objPathMap)
1124 {
1125 pldm_entity node = pldm_entity_extract(entity.second);
1126 auto fruRSI = getRSI(fruRecordSetPDRs, node);
1127
1128 for (const auto& data : fruRecordData)
1129 {
1130 if (!fruRSI || *fruRSI != data.fruRSI)
1131 {
1132 continue;
1133 }
1134
1135 if (data.fruRecType == PLDM_FRU_RECORD_TYPE_OEM)
1136 {
1137 for (const auto& tlv : data.fruTLV)
1138 {
1139 if (tlv.fruFieldType ==
1140 PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE)
1141 {
1142 CustomDBus::getCustomDBus().setLocationCode(
1143 entity.first,
1144 std::string(reinterpret_cast<const char*>(
1145 tlv.fruFieldValue.data()),
1146 tlv.fruFieldLen));
1147 }
1148 }
1149 }
1150 }
1151 }
Patrick Williamsd310f822023-10-07 19:01:19 -05001152#endif
George Liu682ee182020-12-25 15:24:33 +08001153}
Archana Kakanif9355372025-02-04 03:13:24 -06001154
Archana Kakanic3664472025-02-04 05:36:37 -06001155void HostPDRHandler::setPresentPropertyStatus(const std::string& path)
1156{
1157 CustomDBus::getCustomDBus().updateItemPresentStatus(path, true);
1158}
1159
Archana Kakanif9355372025-02-04 03:13:24 -06001160void HostPDRHandler::setAvailabilityState(const std::string& path)
1161{
1162 CustomDBus::getCustomDBus().setAvailabilityState(path, true);
1163}
1164
George Liu682ee182020-12-25 15:24:33 +08001165void HostPDRHandler::createDbusObjects(const PDRList& fruRecordSetPDRs)
1166{
Archana Kakanif9355372025-02-04 03:13:24 -06001167 // Creating and Refreshing dbus hosted by remote PLDM entity Fru PDRs
1168
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001169 for (const auto& entity : objPathMap)
1170 {
Archana Kakanic3664472025-02-04 05:36:37 -06001171 // update the Present Property
1172 setPresentPropertyStatus(entity.first);
Archana Kakanif9355372025-02-04 03:13:24 -06001173 // Implement & update the Availability to true
1174 setAvailabilityState(entity.first);
1175
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001176 pldm_entity node = pldm_entity_extract(entity.second);
1177 switch (node.entity_type)
1178 {
1179 case PLDM_ENTITY_PROC | 0x8000:
1180 CustomDBus::getCustomDBus().implementCpuCoreInterface(
1181 entity.first);
1182 break;
Archana Kakanidb65c3b2025-02-03 05:27:28 -06001183 case PLDM_ENTITY_SYSTEM_CHASSIS:
1184 CustomDBus::getCustomDBus().implementChassisInterface(
1185 entity.first);
1186 break;
Archana Kakani24e9a9b2025-02-04 00:27:25 -06001187 case PLDM_ENTITY_POWER_SUPPLY:
1188 CustomDBus::getCustomDBus().implementPowerSupplyInterface(
1189 entity.first);
1190 break;
Archana Kakani765cf032025-02-04 06:24:14 -06001191 case PLDM_ENTITY_CHASSIS_FRONT_PANEL_BOARD:
1192 CustomDBus::getCustomDBus().implementPanelInterface(
1193 entity.first);
1194 break;
Archana Kakani2832f2c2025-02-04 22:29:30 -06001195 case PLDM_ENTITY_POWER_CONVERTER:
1196 CustomDBus::getCustomDBus().implementVRMInterface(entity.first);
1197 break;
Archana Kakanibf1fd272024-06-05 13:25:53 -05001198 case PLDM_ENTITY_SLOT:
1199 CustomDBus::getCustomDBus().implementPCIeSlotInterface(
1200 entity.first);
1201 break;
Archana Kakani17b1e8a2025-02-04 03:50:24 -06001202 case PLDM_ENTITY_CONNECTOR:
1203 CustomDBus::getCustomDBus().implementConnecterInterface(
1204 entity.first);
1205 break;
Archana Kakanid432b482025-02-04 22:52:28 -06001206 case PLDM_ENTITY_BOARD:
1207 CustomDBus::getCustomDBus().implementBoard(entity.first);
1208 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001209 case PLDM_ENTITY_CARD:
1210 CustomDBus::getCustomDBus().implementPCIeDeviceInterface(
1211 entity.first);
1212 break;
Kamalkumar Patel2ed986c2024-05-08 02:20:47 -05001213 case PLDM_ENTITY_SYS_BOARD:
1214 CustomDBus::getCustomDBus().implementMotherboardInterface(
1215 entity.first);
1216 break;
Archana Kakani413f51e2025-02-03 04:14:36 -06001217 case PLDM_ENTITY_FAN:
1218 CustomDBus::getCustomDBus().implementFanInterface(entity.first);
1219 break;
Archana Kakani42876b62025-02-04 04:22:29 -06001220 case PLDM_ENTITY_IO_MODULE:
1221 CustomDBus::getCustomDBus().implementFabricAdapter(
1222 entity.first);
1223 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001224 default:
1225 break;
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001226 }
1227 }
George Liu682ee182020-12-25 15:24:33 +08001228 getFRURecordTableMetadataByRemote(fruRecordSetPDRs);
1229}
1230
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001231} // namespace pldm