blob: 46d44757a47340cf088d4f48a22284a95137e946 [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>
Alexander Hansen24c04d52025-11-11 14:46:21 +010015#include <xyz/openbmc_project/State/Host/client.hpp>
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050016
Pavithra Barithayab3b84b42024-08-23 11:43:57 +053017#include <cassert>
George Liu6492f522020-06-16 10:34:05 +080018#include <fstream>
George Liu96af8cb2021-07-31 15:23:45 +080019#include <type_traits>
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050020
Riya Dixit49cfb132023-03-02 04:26:53 -060021PHOSPHOR_LOG2_USING;
22
Alexander Hansen24c04d52025-11-11 14:46:21 +010023using HostState = sdbusplus::common::xyz::openbmc_project::state::Host;
24
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050025namespace pldm
26{
Brad Bishop5079ac42021-08-19 18:35:06 -040027using namespace pldm::responder::events;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -050028using namespace pldm::utils;
29using namespace sdbusplus::bus::match::rules;
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050030using namespace pldm::responder::pdr_utils;
Kamalkumar Patel516122e2024-05-07 04:39:32 -050031using namespace pldm::hostbmc::utils;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050032using Json = nlohmann::json;
33namespace fs = std::filesystem;
George Liu682ee182020-12-25 15:24:33 +080034using namespace pldm::dbus;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050035const Json emptyJson{};
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050036
Manojkiran Eda3ca40452021-10-04 22:51:37 +053037template <typename T>
38uint16_t extractTerminusHandle(std::vector<uint8_t>& pdr)
39{
40 T* var = nullptr;
41 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
42 {
43 var = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
44 }
45 else
46 {
47 var = (T*)(pdr.data());
48 }
49 if (var != nullptr)
50 {
51 return var->terminus_handle;
52 }
53 return TERMINUS_HANDLE;
54}
55
George Liu96af8cb2021-07-31 15:23:45 +080056template <typename T>
57void updateContainerId(pldm_entity_association_tree* entityTree,
58 std::vector<uint8_t>& pdr)
59{
60 T* t = nullptr;
61 if (entityTree == nullptr)
62 {
63 return;
64 }
65 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
66 {
67 t = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
68 }
69 else
70 {
71 t = (T*)(pdr.data());
72 }
73 if (t == nullptr)
74 {
75 return;
76 }
77
78 pldm_entity entity{t->entity_type, t->entity_instance, t->container_id};
Patrick Williams16c2a0a2024-08-16 15:20:59 -040079 auto node = pldm_entity_association_tree_find_with_locality(
80 entityTree, &entity, true);
George Liu96af8cb2021-07-31 15:23:45 +080081 if (node)
82 {
83 pldm_entity e = pldm_entity_extract(node);
84 t->container_id = e.entity_container_id;
85 }
86}
87
Tom Joseph74f27c72021-05-16 07:58:53 -070088HostPDRHandler::HostPDRHandler(
Andrew Jeffery3dd444d2024-07-25 22:00:27 +093089 int /* mctp_fd */, uint8_t mctp_eid, sdeventplus::Event& event,
90 pldm_pdr* repo, const std::string& eventsJsonsDir,
91 pldm_entity_association_tree* entityTree,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093092 pldm_entity_association_tree* bmcEntityTree,
93 pldm::InstanceIdDb& instanceIdDb,
George Liua881c172021-06-21 18:28:11 +080094 pldm::requester::Handler<pldm::requester::Request>* handler) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040095 mctp_eid(mctp_eid), event(event), repo(repo),
96 stateSensorHandler(eventsJsonsDir), entityTree(entityTree),
97 instanceIdDb(instanceIdDb), handler(handler),
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -050098 entityMaps(parseEntityMap(ENTITY_MAP_JSON)), oemUtilsHandler(nullptr)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050099{
George Liuacf2c8c2021-05-10 14:08:52 +0800100 mergedHostParents = false;
Patrick Williams84b790c2022-07-22 19:26:56 -0500101 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500102 pldm::utils::DBusHandler::getBus(),
103 propertiesChanged("/xyz/openbmc_project/state/host0",
Alexander Hansen24c04d52025-11-11 14:46:21 +0100104 HostState::interface),
Patrick Williams84b790c2022-07-22 19:26:56 -0500105 [this, repo, entityTree, bmcEntityTree](sdbusplus::message_t& msg) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400106 DbusChangedProps props{};
107 std::string intf;
108 msg.read(intf, props);
Alexander Hansen24c04d52025-11-11 14:46:21 +0100109 const auto itr =
110 props.find(HostState::property_names::current_host_state);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400111 if (itr != props.end())
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500112 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400113 PropertyValue value = itr->second;
114 auto propVal = std::get<std::string>(value);
115 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
116 {
117 // Delete all the remote terminus information
118 std::erase_if(tlPDRInfo, [](const auto& item) {
119 const auto& [key, value] = item;
120 return key != TERMINUS_HANDLE;
121 });
Archana Kakanif9355372025-02-04 03:13:24 -0600122 // when the host is powered off, set the availability
123 // state of all the dbus objects to false
124 this->setPresenceFrus();
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400125 pldm_pdr_remove_remote_pdrs(repo);
126 pldm_entity_association_tree_destroy_root(entityTree);
127 pldm_entity_association_tree_copy_root(bmcEntityTree,
128 entityTree);
129 this->sensorMap.clear();
130 this->responseReceived = false;
131 this->mergedHostParents = false;
Archana Kakani50554252025-03-17 01:37:29 -0500132
133 // After a power off , the remote nodes will be deleted
134 // from the entity association tree, making the nodes point
135 // to junk values, so set them to nullptr
136 for (const auto& element : this->objPathMap)
137 {
138 this->objPathMap[element.first] = nullptr;
139 }
140 }
141 else if (propVal ==
142 "xyz.openbmc_project.State.Host.HostState.Running")
143 {
144 if (oemPlatformHandler)
145 {
146 oemPlatformHandler->handleBootTypesAtPowerOn();
147 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400148 }
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500149 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400150 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500151}
152
Archana Kakanif9355372025-02-04 03:13:24 -0600153void HostPDRHandler::setPresenceFrus()
154{
155 // iterate over all dbus objects
156 for (const auto& [path, entityId] : objPathMap)
157 {
158 CustomDBus::getCustomDBus().setAvailabilityState(path, false);
159 }
160}
161
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500162void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500163{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500164 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500165 modifiedPDRRecordHandles.clear();
166
167 if (isHostPdrModified)
168 {
169 modifiedPDRRecordHandles = std::move(recordHandles);
170 }
171 else
172 {
173 pdrRecordHandles = std::move(recordHandles);
174 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500175
176 // Defer the actual fetch of PDRs from the host (by queuing the call on the
177 // main event loop). That way, we can respond to the platform event msg from
178 // the host firmware.
179 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
180 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
181 std::placeholders::_1));
182}
183
184void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
185{
Sampa Misrac0c79482021-06-02 08:01:54 -0500186 getHostPDR();
187}
188
189void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
190{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500191 pdrFetchEvent.reset();
192
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400193 std::vector<uint8_t> requestMsg(
194 sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530195 auto request = new (requestMsg.data()) pldm_msg;
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500196 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500197 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
198 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500199 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500200 recordHandle = modifiedPDRRecordHandles.front();
201 modifiedPDRRecordHandles.pop_front();
202 }
203 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
204 {
205 recordHandle = pdrRecordHandles.front();
206 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500207 }
208 else
209 {
210 recordHandle = nextRecordHandle;
211 }
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000212 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500213
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400214 auto rc =
215 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
216 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500217 if (rc != PLDM_SUCCESS)
218 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930219 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500220 error("Failed to encode get pdr request, response code '{RC}'", "RC",
221 rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500222 return;
223 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500224
Sampa Misrac0c79482021-06-02 08:01:54 -0500225 rc = handler->registerRequest(
226 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
227 std::move(requestMsg),
Eric Yang70eca962025-05-11 01:48:15 +0800228 [this](mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen) {
229 this->processHostPDRs(eid, response, respMsgLen);
230 });
Sampa Misrac0c79482021-06-02 08:01:54 -0500231 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500232 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500233 error(
234 "Failed to send the getPDR request to remote terminus, response code '{RC}'",
235 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500236 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500237}
238
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600239int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
240 pdr::EventState state)
241{
242 auto rc = stateSensorHandler.eventAction(entry, state);
243 if (rc != PLDM_SUCCESS)
244 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500245 error("Failed to fetch and update D-bus property, response code '{RC}'",
246 "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600247 return rc;
248 }
249 return PLDM_SUCCESS;
250}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500251
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500252void HostPDRHandler::mergeEntityAssociations(
253 const std::vector<uint8_t>& pdr, [[maybe_unused]] const uint32_t& size,
254 [[maybe_unused]] const uint32_t& record_handle)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500255{
256 size_t numEntities{};
257 pldm_entity* entities = nullptr;
258 bool merged = false;
Pavithra Barithaya49575832025-01-29 16:27:30 +0530259 auto entityPdr = new (const_cast<uint8_t*>(pdr.data()) +
260 sizeof(pldm_pdr_hdr)) pldm_pdr_entity_association;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500261
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500262 if (oemPlatformHandler &&
263 oemPlatformHandler->checkRecordHandleInRange(record_handle))
264 {
265 // Adding the remote range PDRs to the repo before merging it
266 uint32_t handle = record_handle;
Andrew Jeffery5a945bd2024-08-01 13:15:36 +0000267 pldm_pdr_add(repo, pdr.data(), size, true, 0xFFFF, &handle);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500268 }
269
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500270 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
271 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800272 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500273 {
George Liuacf2c8c2021-05-10 14:08:52 +0800274 pldm_entity_node* pNode = nullptr;
275 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500276 {
George Liuacf2c8c2021-05-10 14:08:52 +0800277 pNode = pldm_entity_association_tree_find_with_locality(
278 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500279 }
George Liuacf2c8c2021-05-10 14:08:52 +0800280 else
281 {
282 pNode = pldm_entity_association_tree_find_with_locality(
283 entityTree, &entities[0], true);
284 }
285 if (!pNode)
286 {
287 return;
288 }
289
George Liudf9a6d32020-12-22 16:27:16 +0800290 Entities entityAssoc;
291 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800292 for (size_t i = 1; i < numEntities; ++i)
293 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500294 bool isUpdateContainerId = true;
295 if (oemPlatformHandler)
296 {
297 isUpdateContainerId =
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600298 checkIfLogicalBitSet(entities[i].entity_container_id);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500299 }
George Liudf9a6d32020-12-22 16:27:16 +0800300 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800301 entityTree, &entities[i], entities[i].entity_instance_num,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500302 pNode, entityPdr->association_type, true, isUpdateContainerId,
303 0xFFFF);
304 if (!node)
305 {
306 continue;
307 }
George Liuacf2c8c2021-05-10 14:08:52 +0800308 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800309 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800310 }
311
312 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800313 if (merged)
314 {
315 entityAssociations.push_back(entityAssoc);
316 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500317 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500318
319 if (merged)
320 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500321 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500322 pldm_entity_node* node = nullptr;
323 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
324 if (node == nullptr)
325 {
Manojkiran Eda2576aec2024-06-17 12:05:17 +0530326 error("Failed to find reference of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500327 }
328 else
329 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500330 int rc = 0;
331 if (oemPlatformHandler)
332 {
333 auto record = oemPlatformHandler->fetchLastBMCRecord(repo);
334
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400335 uint32_t record_handle =
336 pldm_pdr_get_record_handle(repo, record);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500337
338 rc =
339 pldm_entity_association_pdr_add_from_node_with_record_handle(
340 node, repo, &entities, numEntities, true,
341 TERMINUS_HANDLE, (record_handle + 1));
342 }
343 else
344 {
Andrew Jeffery7761bd22024-08-01 13:15:36 +0000345 rc = pldm_entity_association_pdr_add_from_node(
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500346 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
347 }
348
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930349 if (rc)
350 {
351 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500352 "Failed to add entity association PDR from node, response code '{RC}'",
353 "RC", rc);
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930354 }
Sampa Misra719ed392021-06-04 05:15:13 -0500355 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500356 }
Sampa Misra719ed392021-06-04 05:15:13 -0500357 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500358}
359
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500360void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
361 uint8_t eventDataFormat)
362{
363 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
364
365 // Extract from the PDR repo record handles of PDRs we want the host
366 // to pull up.
367 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
368 std::vector<uint8_t> numsOfChangeEntries(1);
369 std::vector<std::vector<ChangeEntry>> changeEntries(
370 numsOfChangeEntries.size());
371 for (auto pdrType : pdrTypes)
372 {
373 const pldm_pdr_record* record{};
374 do
375 {
376 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
377 nullptr, nullptr);
378 if (record && pldm_pdr_record_is_remote(record))
379 {
380 changeEntries[0].push_back(
381 pldm_pdr_get_record_handle(repo, record));
382 }
383 } while (record);
384 }
385 if (changeEntries.empty())
386 {
387 return;
388 }
389 numsOfChangeEntries[0] = changeEntries[0].size();
390
391 // Encode PLDM platform event msg to indicate a PDR repo change.
392 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
393 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
394 changeEntries[0].size() * sizeof(uint32_t);
395 std::vector<uint8_t> eventDataVec{};
396 eventDataVec.resize(maxSize);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530397 auto eventData = new (eventDataVec.data())
398 pldm_pdr_repository_chg_event_data;
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500399 size_t actualSize{};
400 auto firstEntry = changeEntries[0].data();
401 auto rc = encode_pldm_pdr_repository_chg_event_data(
402 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
403 &firstEntry, eventData, &actualSize, maxSize);
404 if (rc != PLDM_SUCCESS)
405 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500406 error(
407 "Failed to encode pldm pdr repository change event data, response code '{RC}'",
408 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500409 return;
410 }
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000411 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400412 std::vector<uint8_t> requestMsg(
413 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
414 actualSize);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530415 auto request = new (requestMsg.data()) pldm_msg;
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500416 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600417 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
418 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500419 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500420 if (rc != PLDM_SUCCESS)
421 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930422 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500423 error(
424 "Failed to encode platform event message request, response code '{RC}'",
425 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500426 return;
427 }
428
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400429 auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/,
430 const pldm_msg* response,
431 size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700432 if (response == nullptr || !respMsgLen)
433 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600434 error(
435 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700436 return;
437 }
438
439 uint8_t completionCode{};
440 uint8_t status{};
441 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500442 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
443 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500444 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700445 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600446 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500447 "Failed to decode platform event message response, response code '{RC}' and completion code '{CC}'",
448 "RC", rc, "CC", completionCode);
Tom Joseph74f27c72021-05-16 07:58:53 -0700449 }
450 };
451
Sampa Misrac0c79482021-06-02 08:01:54 -0500452 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500453 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700454 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500455 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500456 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500457 error(
458 "Failed to send the PDR repository changed event request, response code '{RC}'",
459 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500460 }
461}
462
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530463void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500464{
465 for (const auto& pdr : stateSensorPDRs)
466 {
467 SensorEntry sensorEntry{};
468 const auto& [terminusHandle, sensorID, sensorInfo] =
469 responder::pdr_utils::parseStateSensorPDR(pdr);
470 sensorEntry.sensorID = sensorID;
471 try
472 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530473 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500474 }
475 // If there is no mapping for terminusHandle assign the reserved TID
476 // value of 0xFF to indicate that.
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500477 catch (const std::out_of_range&)
Sampa Misra868c8792020-05-26 03:12:13 -0500478 {
479 sensorEntry.terminusID = PLDM_TID_RESERVED;
480 }
481 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
482 }
483}
484
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400485void HostPDRHandler::processHostPDRs(
486 mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen)
Sampa Misrac0c79482021-06-02 08:01:54 -0500487{
488 static bool merged = false;
489 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800490 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500491 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600492 uint8_t tlEid = 0;
493 bool tlValid = true;
494 uint32_t rh = 0;
495 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530496 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600497 uint8_t tid = 0;
498
Sampa Misrac0c79482021-06-02 08:01:54 -0500499 uint8_t completionCode{};
500 uint32_t nextDataTransferHandle{};
501 uint8_t transferFlag{};
502 uint16_t respCount{};
503 uint8_t transferCRC{};
504 if (response == nullptr || !respMsgLen)
505 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600506 error("Failed to receive response for the GetPDR command");
Riya Dixit478e71d2024-06-21 14:10:14 -0500507 pldm::utils::reportError(
508 "xyz.openbmc_project.PLDM.Error.GetPDR.PDRExchangeFailure");
Sampa Misrac0c79482021-06-02 08:01:54 -0500509 return;
510 }
511
512 auto rc = decode_get_pdr_resp(
513 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
514 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
515 nullptr, 0, &transferCRC);
516 std::vector<uint8_t> responsePDRMsg;
517 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
518 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500519 if (rc != PLDM_SUCCESS)
520 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500521 error(
522 "Failed to decode getPDR response for next record handle '{NEXT_RECORD_HANDLE}', response code '{RC}'",
523 "NEXT_RECORD_HANDLE", nextRecordHandle, "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500524 return;
525 }
526 else
527 {
528 std::vector<uint8_t> pdr(respCount, 0);
529 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
530 &nextRecordHandle, &nextDataTransferHandle,
531 &transferFlag, &respCount, pdr.data(),
532 respCount, &transferCRC);
533 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
534 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500535 error(
536 "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}'",
537 "NEXT_RECORD_HANDLE", nextRecordHandle, "DATA_TRANSFER_HANDLE",
538 nextDataTransferHandle, "FLAG", transferFlag, "RC", rc, "CC",
539 completionCode);
Sampa Misrac0c79482021-06-02 08:01:54 -0500540 return;
541 }
542 else
543 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600544 // when nextRecordHandle is 0, we need the recordHandle of the last
545 // PDR and not 0-1.
546 if (!nextRecordHandle)
547 {
548 rh = nextRecordHandle;
549 }
550 else
551 {
552 rh = nextRecordHandle - 1;
553 }
554
Pavithra Barithaya49575832025-01-29 16:27:30 +0530555 auto pdrHdr = new (pdr.data()) pldm_pdr_hdr;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600556 if (!rh)
557 {
558 rh = pdrHdr->record_handle;
559 }
560
Sampa Misrac0c79482021-06-02 08:01:54 -0500561 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
562 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500563 this->mergeEntityAssociations(pdr, respCount, rh);
Sampa Misrac0c79482021-06-02 08:01:54 -0500564 merged = true;
565 }
566 else
567 {
568 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
569 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530570 pdrTerminusHandle =
571 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500572 auto tlpdr =
573 reinterpret_cast<const pldm_terminus_locator_pdr*>(
574 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600575
576 terminusHandle = tlpdr->terminus_handle;
577 tid = tlpdr->tid;
578 auto terminus_locator_type = tlpdr->terminus_locator_type;
579 if (terminus_locator_type ==
580 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
581 {
582 auto locatorValue = reinterpret_cast<
583 const pldm_terminus_locator_type_mctp_eid*>(
584 tlpdr->terminus_locator_value);
585 tlEid = static_cast<uint8_t>(locatorValue->eid);
586 }
587 if (tlpdr->validity == 0)
588 {
589 tlValid = false;
590 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500591 for (const auto& terminusMap : tlPDRInfo)
592 {
593 if ((terminusHandle == (terminusMap.first)) &&
594 (get<1>(terminusMap.second) == tlEid) &&
595 (get<2>(terminusMap.second) == tlpdr->validity))
596 {
597 // TL PDR already present with same validity don't
598 // add the PDR to the repo just return
599 return;
600 }
601 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530602 tlPDRInfo.insert_or_assign(
603 tlpdr->terminus_handle,
604 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500605 }
606 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
607 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530608 pdrTerminusHandle =
609 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800610 updateContainerId<pldm_state_sensor_pdr>(entityTree, pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500611 stateSensorPDRs.emplace_back(pdr);
612 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530613 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
614 {
615 pdrTerminusHandle =
616 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800617 updateContainerId<pldm_pdr_fru_record_set>(entityTree, pdr);
George Liu682ee182020-12-25 15:24:33 +0800618 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530619 }
620 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
621 {
622 pdrTerminusHandle =
623 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800624 updateContainerId<pldm_state_effecter_pdr>(entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530625 }
626 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
627 {
628 pdrTerminusHandle =
629 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
630 pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800631 updateContainerId<pldm_numeric_effecter_value_pdr>(
632 entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530633 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600634 // if the TLPDR is invalid update the repo accordingly
635 if (!tlValid)
636 {
637 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
638 tlValid);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500639
640 if (!isHostUp())
641 {
642 // The terminus PDR becomes invalid when the terminus
643 // itself is down. We don't need to do PDR exchange in
644 // that case, so setting the next record handle to 0.
645 nextRecordHandle = 0;
646 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600647 }
648 else
649 {
Andrew Jeffery5a945bd2024-08-01 13:15:36 +0000650 rc = pldm_pdr_add(repo, pdr.data(), respCount, true,
651 pdrTerminusHandle, &rh);
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930652 if (rc)
653 {
654 // pldm_pdr_add() assert()ed on failure to add a PDR.
655 throw std::runtime_error("Failed to add PDR");
656 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600657 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500658 }
659 }
660 }
661 if (!nextRecordHandle)
662 {
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500663 updateEntityAssociation(entityAssociations, entityTree, objPathMap,
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500664 entityMaps, oemPlatformHandler);
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -0500665 if (oemUtilsHandler)
666 {
667 oemUtilsHandler->setCoreCount(entityAssociations, entityMaps);
668 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500669 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530670 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800671 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600672 if (isHostUp())
673 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530674 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600675 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500676 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800677 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800678 entityAssociations.clear();
679
Sampa Misrac0c79482021-06-02 08:01:54 -0500680 if (merged)
681 {
682 merged = false;
683 deferredPDRRepoChgEvent =
684 std::make_unique<sdeventplus::source::Defer>(
685 event,
686 std::bind(
687 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
688 this, std::placeholders::_1));
689 }
690 }
691 else
692 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500693 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
694 {
695 isHostPdrModified = false;
696 }
697 else
698 {
699 deferredFetchPDREvent =
700 std::make_unique<sdeventplus::source::Defer>(
701 event,
702 std::bind(
703 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
704 this, nextRecordHandle, std::placeholders::_1));
705 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500706 }
707}
708
709void HostPDRHandler::_processPDRRepoChgEvent(
710 sdeventplus::source::EventBase& /*source */)
711{
712 deferredPDRRepoChgEvent.reset();
713 this->sendPDRRepositoryChgEvent(
Andrew Jefferyc14fb4b2024-07-25 22:13:09 +0930714 std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION),
Sampa Misrac0c79482021-06-02 08:01:54 -0500715 FORMAT_IS_PDR_HANDLES);
716}
717
718void HostPDRHandler::_processFetchPDREvent(
719 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
720{
721 deferredFetchPDREvent.reset();
722 if (!this->pdrRecordHandles.empty())
723 {
724 nextRecordHandle = this->pdrRecordHandles.front();
725 this->pdrRecordHandles.pop_front();
726 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500727 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
728 {
729 nextRecordHandle = this->modifiedPDRRecordHandles.front();
730 this->modifiedPDRRecordHandles.pop_front();
731 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500732 this->getHostPDR(nextRecordHandle);
733}
734
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500735void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530736{
sampmisr6decfc12021-03-02 11:07:36 +0530737 responseReceived = false;
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000738 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400739 std::vector<uint8_t> requestMsg(
740 sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530741 auto request = new (requestMsg.data()) pldm_msg;
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500742 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
743 PLDM_BASE, request);
744 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530745 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500746 error("Failed to encode GetPLDMVersion, response code {RC}", "RC",
Riya Dixit49cfb132023-03-02 04:26:53 -0600747 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930748 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530749 return;
750 }
751
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500752 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
753 const pldm_msg* response,
754 size_t respMsgLen) {
755 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530756 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600757 error(
758 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530759 return;
760 }
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500761 info("Getting the response code '{RC}'", "RC", lg2::hex,
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500762 response->payload[0]);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500763 this->responseReceived = true;
sampmisr6decfc12021-03-02 11:07:36 +0530764 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500765 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
766 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
767 std::move(getPLDMVersionHandler));
768 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530769 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500770 error(
771 "Failed to discover remote terminus state. Assuming remote terminus as off");
sampmisr6decfc12021-03-02 11:07:36 +0530772 }
773}
774
775bool HostPDRHandler::isHostUp()
776{
777 return responseReceived;
778}
779
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530780void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600781{
782 for (const auto& stateSensorPDR : stateSensorPDRs)
783 {
784 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
785 stateSensorPDR.data());
786
787 if (!pdr)
788 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500789 error("Failed to get state sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600790 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530791 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600792 return;
793 }
794
795 uint16_t sensorId = pdr->sensor_id;
796
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530797 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600798 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530799 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600800 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530801 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600802 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530803 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600804 }
805
806 bitfield8_t sensorRearm;
807 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530808 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600809
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000810 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600811 std::vector<uint8_t> requestMsg(
812 sizeof(pldm_msg_hdr) +
813 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530814 auto request = new (requestMsg.data()) pldm_msg;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600815 auto rc = encode_get_state_sensor_readings_req(
816 instanceId, sensorId, sensorRearm, 0, request);
817
818 if (rc != PLDM_SUCCESS)
819 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930820 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600821 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500822 "Failed to encode get state sensor readings request for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
823 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
824 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600825 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530826 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600827 return;
828 }
829
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400830 auto getStateSensorReadingRespHandler = [=, this](
831 mctp_eid_t /*eid*/,
832 const pldm_msg*
833 response,
834 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600835 if (response == nullptr || !respMsgLen)
836 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600837 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500838 "Failed to receive response for get state sensor reading command for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}'",
839 "SENSOR_ID", sensorId, "INSTANCE", instanceId);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600840 return;
841 }
842 std::array<get_sensor_state_field, 8> stateField{};
843 uint8_t completionCode = 0;
844 uint8_t comp_sensor_count = 0;
845
846 auto rc = decode_get_state_sensor_readings_resp(
847 response, respMsgLen, &completionCode,
848 &comp_sensor_count, stateField.data());
849
850 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
851 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600852 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500853 "Failed to decode get state sensor readings response for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code'{RC}' and completion code '{CC}'",
854 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
855 rc, "CC", completionCode);
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530856 pldm::utils::reportError(
857 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600858 }
859
860 uint8_t eventState;
861 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600862
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500863 for (uint8_t sensorOffset = 0;
864 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600865 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500866 eventState = stateField[sensorOffset].present_state;
867 previousEventState =
868 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600869
870 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
871 eventState,
872 previousEventState);
873
874 SensorEntry sensorEntry{tid, sensorId};
875
876 pldm::pdr::EntityInfo entityInfo{};
877 pldm::pdr::CompositeSensorStates
878 compositeSensorStates{};
Sagar Srinivase3607a32024-02-16 03:50:53 -0600879 std::vector<pldm::pdr::StateSetId> stateSetIds{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600880
881 try
882 {
Sagar Srinivase3607a32024-02-16 03:50:53 -0600883 std::tie(entityInfo, compositeSensorStates,
884 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600885 lookupSensorInfo(sensorEntry);
886 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500887 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600888 {
889 try
890 {
891 sensorEntry.terminusID = PLDM_TID_RESERVED;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600892 std::tie(entityInfo, compositeSensorStates,
893 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600894 lookupSensorInfo(sensorEntry);
895 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500896 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600897 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600898 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600899 }
900 }
901
Manojkiran Eda07a07e22024-04-24 19:15:10 +0530902 if ((compositeSensorStates.size() > 1) &&
903 (sensorOffset > (compositeSensorStates.size() - 1)))
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600904 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500905 error(
906 "Error Invalid data, Invalid sensor offset '{SENSOR_OFFSET}'",
907 "SENSOR_OFFSET", sensorOffset);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600908 return;
909 }
910
911 const auto& possibleStates =
912 compositeSensorStates[sensorOffset];
913 if (possibleStates.find(eventState) ==
914 possibleStates.end())
915 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500916 error(
917 "Error invalid_data, Invalid event state '{STATE}'",
918 "STATE", eventState);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600919 return;
920 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400921 const auto& [containerId, entityType, entityInstance] =
922 entityInfo;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600923 auto stateSetId = stateSetIds[sensorOffset];
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600924 pldm::responder::events::StateSensorEntry
Manojkiran Edafa084702024-05-27 10:20:30 +0530925 stateSensorEntry{containerId, entityType,
Sagar Srinivase3607a32024-02-16 03:50:53 -0600926 entityInstance, sensorOffset,
Manojkiran Edafa084702024-05-27 10:20:30 +0530927 stateSetId, false};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600928 handleStateSensorEvent(stateSensorEntry, eventState);
929 }
930 };
931
932 rc = handler->registerRequest(
933 mctp_eid, instanceId, PLDM_PLATFORM,
934 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg),
935 std::move(getStateSensorReadingRespHandler));
936
937 if (rc != PLDM_SUCCESS)
938 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600939 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500940 "Failed to send request to get state sensor reading on remote terminus for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
941 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
942 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600943 }
944 }
945 }
946 }
947}
George Liu682ee182020-12-25 15:24:33 +0800948
949void HostPDRHandler::getFRURecordTableMetadataByRemote(
950 const PDRList& fruRecordSetPDRs)
951{
ManojKiran Eda22bcb072025-07-11 23:49:43 +0000952 auto instanceId = instanceIdDb.next(mctp_eid);
George Liu682ee182020-12-25 15:24:33 +0800953 std::vector<uint8_t> requestMsg(
954 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
955
956 // GetFruRecordTableMetadata
Pavithra Barithaya49575832025-01-29 16:27:30 +0530957 auto request = new (requestMsg.data()) pldm_msg;
George Liu682ee182020-12-25 15:24:33 +0800958 auto rc = encode_get_fru_record_table_metadata_req(
959 instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
960 if (rc != PLDM_SUCCESS)
961 {
962 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500963 error(
964 "Failed to encode get fru record table metadata request, response code '{RC}'",
George Liu682ee182020-12-25 15:24:33 +0800965 "RC", lg2::hex, rc);
966 return;
967 }
968
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400969 auto getFruRecordTableMetadataResponseHandler = [this, fruRecordSetPDRs](
970 mctp_eid_t /*eid*/,
971 const pldm_msg*
972 response,
973 size_t respMsgLen) {
George Liu682ee182020-12-25 15:24:33 +0800974 if (response == nullptr || !respMsgLen)
975 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500976 error(
977 "Failed to receive response for the get fru record table metadata");
George Liu682ee182020-12-25 15:24:33 +0800978 return;
979 }
980
981 uint8_t cc = 0;
982 uint8_t fru_data_major_version, fru_data_minor_version;
983 uint32_t fru_table_maximum_size, fru_table_length;
984 uint16_t total_record_set_identifiers;
985 uint16_t total;
986 uint32_t checksum;
987
988 auto rc = decode_get_fru_record_table_metadata_resp(
989 response, respMsgLen, &cc, &fru_data_major_version,
990 &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
991 &total_record_set_identifiers, &total, &checksum);
992
993 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
994 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500995 error(
996 "Failed to decode get fru record table metadata response, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +0800997 "RC", lg2::hex, rc, "CC", cc);
998 return;
999 }
1000
1001 // pass total to getFRURecordTableByRemote
1002 this->getFRURecordTableByRemote(fruRecordSetPDRs, total);
1003 };
1004
1005 rc = handler->registerRequest(
1006 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA,
1007 std::move(requestMsg),
1008 std::move(getFruRecordTableMetadataResponseHandler));
1009 if (rc != PLDM_SUCCESS)
1010 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001011 error(
1012 "Failed to send the the set state effecter states request, response code '{RC}'",
1013 "RC", rc);
George Liu682ee182020-12-25 15:24:33 +08001014 }
1015
1016 return;
1017}
1018
1019void HostPDRHandler::getFRURecordTableByRemote(const PDRList& fruRecordSetPDRs,
1020 uint16_t totalTableRecords)
1021{
1022 fruRecordData.clear();
1023
1024 if (!totalTableRecords)
1025 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001026 error("Failed to get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001027 return;
1028 }
1029
ManojKiran Eda22bcb072025-07-11 23:49:43 +00001030 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001031 std::vector<uint8_t> requestMsg(
1032 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
George Liu682ee182020-12-25 15:24:33 +08001033
1034 // send the getFruRecordTable command
Pavithra Barithaya49575832025-01-29 16:27:30 +05301035 auto request = new (requestMsg.data()) pldm_msg;
George Liu682ee182020-12-25 15:24:33 +08001036 auto rc = encode_get_fru_record_table_req(
1037 instanceId, 0, PLDM_GET_FIRSTPART, request,
1038 requestMsg.size() - sizeof(pldm_msg_hdr));
1039 if (rc != PLDM_SUCCESS)
1040 {
1041 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001042 error(
1043 "Failed to encode get fru record table request, response code '{RC}'",
1044 "RC", lg2::hex, rc);
George Liu682ee182020-12-25 15:24:33 +08001045 return;
1046 }
1047
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001048 auto getFruRecordTableResponseHandler = [totalTableRecords, this,
1049 fruRecordSetPDRs](
1050 mctp_eid_t /*eid*/,
1051 const pldm_msg* response,
1052 size_t respMsgLen) {
George Liu682ee182020-12-25 15:24:33 +08001053 if (response == nullptr || !respMsgLen)
1054 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001055 error("Failed to receive response for the get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001056 return;
1057 }
1058
1059 uint8_t cc = 0;
1060 uint32_t next_data_transfer_handle = 0;
1061 uint8_t transfer_flag = 0;
1062 size_t fru_record_table_length = 0;
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001063 std::vector<uint8_t> fru_record_table_data(
1064 respMsgLen - sizeof(pldm_msg_hdr));
George Liu682ee182020-12-25 15:24:33 +08001065 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
1066 auto rc = decode_get_fru_record_table_resp(
Manojkiran Eda33a9cd02024-01-22 11:06:59 +05301067 responsePtr, respMsgLen, &cc, &next_data_transfer_handle,
1068 &transfer_flag, fru_record_table_data.data(),
1069 &fru_record_table_length);
George Liu682ee182020-12-25 15:24:33 +08001070
1071 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
1072 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001073 error(
1074 "Failed to decode get fru record table resp, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +08001075 "RC", lg2::hex, rc, "CC", cc);
1076 return;
1077 }
1078
1079 fruRecordData = responder::pdr_utils::parseFruRecordTable(
1080 fru_record_table_data.data(), fru_record_table_length);
1081
1082 if (totalTableRecords != fruRecordData.size())
1083 {
1084 fruRecordData.clear();
1085
Manojkiran Eda2576aec2024-06-17 12:05:17 +05301086 error("Failed to parse fru record data format.");
George Liu682ee182020-12-25 15:24:33 +08001087 return;
1088 }
1089
1090 this->setFRUDataOnDBus(fruRecordSetPDRs, fruRecordData);
1091 };
1092
1093 rc = handler->registerRequest(
1094 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE,
1095 std::move(requestMsg), std::move(getFruRecordTableResponseHandler));
1096 if (rc != PLDM_SUCCESS)
1097 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001098 error("Failed to send the the set state effecter states request");
George Liu682ee182020-12-25 15:24:33 +08001099 }
1100}
1101
1102std::optional<uint16_t> HostPDRHandler::getRSI(const PDRList& fruRecordSetPDRs,
1103 const pldm_entity& entity)
1104{
1105 for (const auto& pdr : fruRecordSetPDRs)
1106 {
1107 auto fruPdr = reinterpret_cast<const pldm_pdr_fru_record_set*>(
1108 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
1109
1110 if (fruPdr->entity_type == entity.entity_type &&
Sagar Srinivasebf8bb52023-10-06 01:15:55 -05001111 fruPdr->entity_instance == entity.entity_instance_num &&
1112 fruPdr->container_id == entity.entity_container_id)
George Liu682ee182020-12-25 15:24:33 +08001113 {
1114 return fruPdr->fru_rsi;
1115 }
1116 }
1117
1118 return std::nullopt;
1119}
1120
1121void HostPDRHandler::setFRUDataOnDBus(
Patrick Williamsd310f822023-10-07 19:01:19 -05001122 [[maybe_unused]] const PDRList& fruRecordSetPDRs,
1123 [[maybe_unused]] const std::vector<
1124 responder::pdr_utils::FruRecordDataFormat>& fruRecordData)
George Liu682ee182020-12-25 15:24:33 +08001125{
Patrick Williamsd310f822023-10-07 19:01:19 -05001126#ifdef OEM_IBM
George Liu682ee182020-12-25 15:24:33 +08001127 for (const auto& entity : objPathMap)
1128 {
1129 pldm_entity node = pldm_entity_extract(entity.second);
1130 auto fruRSI = getRSI(fruRecordSetPDRs, node);
1131
1132 for (const auto& data : fruRecordData)
1133 {
1134 if (!fruRSI || *fruRSI != data.fruRSI)
1135 {
1136 continue;
1137 }
1138
1139 if (data.fruRecType == PLDM_FRU_RECORD_TYPE_OEM)
1140 {
1141 for (const auto& tlv : data.fruTLV)
1142 {
1143 if (tlv.fruFieldType ==
1144 PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE)
1145 {
1146 CustomDBus::getCustomDBus().setLocationCode(
1147 entity.first,
1148 std::string(reinterpret_cast<const char*>(
1149 tlv.fruFieldValue.data()),
1150 tlv.fruFieldLen));
1151 }
1152 }
1153 }
1154 }
1155 }
Patrick Williamsd310f822023-10-07 19:01:19 -05001156#endif
George Liu682ee182020-12-25 15:24:33 +08001157}
Archana Kakanif9355372025-02-04 03:13:24 -06001158
Archana Kakanic3664472025-02-04 05:36:37 -06001159void HostPDRHandler::setPresentPropertyStatus(const std::string& path)
1160{
1161 CustomDBus::getCustomDBus().updateItemPresentStatus(path, true);
1162}
1163
Archana Kakanif9355372025-02-04 03:13:24 -06001164void HostPDRHandler::setAvailabilityState(const std::string& path)
1165{
1166 CustomDBus::getCustomDBus().setAvailabilityState(path, true);
1167}
1168
George Liu682ee182020-12-25 15:24:33 +08001169void HostPDRHandler::createDbusObjects(const PDRList& fruRecordSetPDRs)
1170{
Archana Kakanif9355372025-02-04 03:13:24 -06001171 // Creating and Refreshing dbus hosted by remote PLDM entity Fru PDRs
1172
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001173 for (const auto& entity : objPathMap)
1174 {
Archana Kakanic3664472025-02-04 05:36:37 -06001175 // update the Present Property
1176 setPresentPropertyStatus(entity.first);
Archana Kakanif9355372025-02-04 03:13:24 -06001177 // Implement & update the Availability to true
1178 setAvailabilityState(entity.first);
1179
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001180 pldm_entity node = pldm_entity_extract(entity.second);
1181 switch (node.entity_type)
1182 {
1183 case PLDM_ENTITY_PROC | 0x8000:
1184 CustomDBus::getCustomDBus().implementCpuCoreInterface(
1185 entity.first);
1186 break;
Archana Kakanidb65c3b2025-02-03 05:27:28 -06001187 case PLDM_ENTITY_SYSTEM_CHASSIS:
1188 CustomDBus::getCustomDBus().implementChassisInterface(
1189 entity.first);
1190 break;
Archana Kakani24e9a9b2025-02-04 00:27:25 -06001191 case PLDM_ENTITY_POWER_SUPPLY:
1192 CustomDBus::getCustomDBus().implementPowerSupplyInterface(
1193 entity.first);
1194 break;
Archana Kakani765cf032025-02-04 06:24:14 -06001195 case PLDM_ENTITY_CHASSIS_FRONT_PANEL_BOARD:
1196 CustomDBus::getCustomDBus().implementPanelInterface(
1197 entity.first);
1198 break;
Archana Kakani2832f2c2025-02-04 22:29:30 -06001199 case PLDM_ENTITY_POWER_CONVERTER:
1200 CustomDBus::getCustomDBus().implementVRMInterface(entity.first);
1201 break;
Archana Kakanibf1fd272024-06-05 13:25:53 -05001202 case PLDM_ENTITY_SLOT:
1203 CustomDBus::getCustomDBus().implementPCIeSlotInterface(
1204 entity.first);
1205 break;
Archana Kakani17b1e8a2025-02-04 03:50:24 -06001206 case PLDM_ENTITY_CONNECTOR:
1207 CustomDBus::getCustomDBus().implementConnecterInterface(
1208 entity.first);
1209 break;
Archana Kakanid432b482025-02-04 22:52:28 -06001210 case PLDM_ENTITY_BOARD:
1211 CustomDBus::getCustomDBus().implementBoard(entity.first);
1212 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001213 case PLDM_ENTITY_CARD:
1214 CustomDBus::getCustomDBus().implementPCIeDeviceInterface(
1215 entity.first);
1216 break;
Kamalkumar Patel2ed986c2024-05-08 02:20:47 -05001217 case PLDM_ENTITY_SYS_BOARD:
1218 CustomDBus::getCustomDBus().implementMotherboardInterface(
1219 entity.first);
1220 break;
Archana Kakani413f51e2025-02-03 04:14:36 -06001221 case PLDM_ENTITY_FAN:
1222 CustomDBus::getCustomDBus().implementFanInterface(entity.first);
1223 break;
Archana Kakani42876b62025-02-04 04:22:29 -06001224 case PLDM_ENTITY_IO_MODULE:
1225 CustomDBus::getCustomDBus().implementFabricAdapter(
1226 entity.first);
1227 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001228 default:
1229 break;
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001230 }
1231 }
George Liu682ee182020-12-25 15:24:33 +08001232 getFRURecordTableMetadataByRemote(fruRecordSetPDRs);
1233}
1234
Pavithra Barithaya273bee22025-08-22 15:38:21 +05301235void HostPDRHandler::deletePDRFromRepo(PDRRecordHandles&& recordHandles)
1236{
1237 for (auto& recordHandle : recordHandles)
1238 {
1239 int rc = pldm_pdr_delete_by_record_handle(repo, recordHandle, true);
1240 if (rc)
1241 {
1242 error("Failed to delete the record handle: {REC_HANDLE}",
1243 "REC_HANDLE", recordHandle);
1244 }
1245 }
1246}
1247
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001248} // namespace pldm