blob: 052e7e21a92a09d90b84982267a5f922a595c816 [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;
128 }
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500129 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400130 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500131}
132
Archana Kakanif9355372025-02-04 03:13:24 -0600133void HostPDRHandler::setPresenceFrus()
134{
135 // iterate over all dbus objects
136 for (const auto& [path, entityId] : objPathMap)
137 {
138 CustomDBus::getCustomDBus().setAvailabilityState(path, false);
139 }
140}
141
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500142void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500143{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500144 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500145 modifiedPDRRecordHandles.clear();
146
147 if (isHostPdrModified)
148 {
149 modifiedPDRRecordHandles = std::move(recordHandles);
150 }
151 else
152 {
153 pdrRecordHandles = std::move(recordHandles);
154 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500155
156 // Defer the actual fetch of PDRs from the host (by queuing the call on the
157 // main event loop). That way, we can respond to the platform event msg from
158 // the host firmware.
159 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
160 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
161 std::placeholders::_1));
162}
163
164void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
165{
Sampa Misrac0c79482021-06-02 08:01:54 -0500166 getHostPDR();
167}
168
169void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
170{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500171 pdrFetchEvent.reset();
172
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400173 std::vector<uint8_t> requestMsg(
174 sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530175 auto request = new (requestMsg.data()) pldm_msg;
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500176 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500177 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
178 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500179 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500180 recordHandle = modifiedPDRRecordHandles.front();
181 modifiedPDRRecordHandles.pop_front();
182 }
183 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
184 {
185 recordHandle = pdrRecordHandles.front();
186 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500187 }
188 else
189 {
190 recordHandle = nextRecordHandle;
191 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930192 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500193
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400194 auto rc =
195 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
196 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500197 if (rc != PLDM_SUCCESS)
198 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930199 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500200 error("Failed to encode get pdr request, response code '{RC}'", "RC",
201 rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500202 return;
203 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500204
Sampa Misrac0c79482021-06-02 08:01:54 -0500205 rc = handler->registerRequest(
206 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
207 std::move(requestMsg),
Andrew Jefferyc14fb4b2024-07-25 22:13:09 +0930208 std::bind_front(&HostPDRHandler::processHostPDRs, this));
Sampa Misrac0c79482021-06-02 08:01:54 -0500209 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500210 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500211 error(
212 "Failed to send the getPDR request to remote terminus, response code '{RC}'",
213 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500214 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500215}
216
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600217int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
218 pdr::EventState state)
219{
220 auto rc = stateSensorHandler.eventAction(entry, state);
221 if (rc != PLDM_SUCCESS)
222 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500223 error("Failed to fetch and update D-bus property, response code '{RC}'",
224 "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600225 return rc;
226 }
227 return PLDM_SUCCESS;
228}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500229
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500230void HostPDRHandler::mergeEntityAssociations(
231 const std::vector<uint8_t>& pdr, [[maybe_unused]] const uint32_t& size,
232 [[maybe_unused]] const uint32_t& record_handle)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500233{
234 size_t numEntities{};
235 pldm_entity* entities = nullptr;
236 bool merged = false;
Pavithra Barithaya49575832025-01-29 16:27:30 +0530237 auto entityPdr = new (const_cast<uint8_t*>(pdr.data()) +
238 sizeof(pldm_pdr_hdr)) pldm_pdr_entity_association;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500239
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500240 if (oemPlatformHandler &&
241 oemPlatformHandler->checkRecordHandleInRange(record_handle))
242 {
243 // Adding the remote range PDRs to the repo before merging it
244 uint32_t handle = record_handle;
Andrew Jeffery5a945bd2024-08-01 13:15:36 +0000245 pldm_pdr_add(repo, pdr.data(), size, true, 0xFFFF, &handle);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500246 }
247
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500248 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
249 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800250 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500251 {
George Liuacf2c8c2021-05-10 14:08:52 +0800252 pldm_entity_node* pNode = nullptr;
253 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500254 {
George Liuacf2c8c2021-05-10 14:08:52 +0800255 pNode = pldm_entity_association_tree_find_with_locality(
256 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500257 }
George Liuacf2c8c2021-05-10 14:08:52 +0800258 else
259 {
260 pNode = pldm_entity_association_tree_find_with_locality(
261 entityTree, &entities[0], true);
262 }
263 if (!pNode)
264 {
265 return;
266 }
267
George Liudf9a6d32020-12-22 16:27:16 +0800268 Entities entityAssoc;
269 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800270 for (size_t i = 1; i < numEntities; ++i)
271 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500272 bool isUpdateContainerId = true;
273 if (oemPlatformHandler)
274 {
275 isUpdateContainerId =
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600276 checkIfLogicalBitSet(entities[i].entity_container_id);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500277 }
George Liudf9a6d32020-12-22 16:27:16 +0800278 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800279 entityTree, &entities[i], entities[i].entity_instance_num,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500280 pNode, entityPdr->association_type, true, isUpdateContainerId,
281 0xFFFF);
282 if (!node)
283 {
284 continue;
285 }
George Liuacf2c8c2021-05-10 14:08:52 +0800286 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800287 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800288 }
289
290 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800291 if (merged)
292 {
293 entityAssociations.push_back(entityAssoc);
294 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500295 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500296
297 if (merged)
298 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500299 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500300 pldm_entity_node* node = nullptr;
301 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
302 if (node == nullptr)
303 {
Manojkiran Eda2576aec2024-06-17 12:05:17 +0530304 error("Failed to find reference of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500305 }
306 else
307 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500308 int rc = 0;
309 if (oemPlatformHandler)
310 {
311 auto record = oemPlatformHandler->fetchLastBMCRecord(repo);
312
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400313 uint32_t record_handle =
314 pldm_pdr_get_record_handle(repo, record);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500315
316 rc =
317 pldm_entity_association_pdr_add_from_node_with_record_handle(
318 node, repo, &entities, numEntities, true,
319 TERMINUS_HANDLE, (record_handle + 1));
320 }
321 else
322 {
Andrew Jeffery7761bd22024-08-01 13:15:36 +0000323 rc = pldm_entity_association_pdr_add_from_node(
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500324 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
325 }
326
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930327 if (rc)
328 {
329 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500330 "Failed to add entity association PDR from node, response code '{RC}'",
331 "RC", rc);
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930332 }
Sampa Misra719ed392021-06-04 05:15:13 -0500333 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500334 }
Sampa Misra719ed392021-06-04 05:15:13 -0500335 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500336}
337
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500338void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
339 uint8_t eventDataFormat)
340{
341 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
342
343 // Extract from the PDR repo record handles of PDRs we want the host
344 // to pull up.
345 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
346 std::vector<uint8_t> numsOfChangeEntries(1);
347 std::vector<std::vector<ChangeEntry>> changeEntries(
348 numsOfChangeEntries.size());
349 for (auto pdrType : pdrTypes)
350 {
351 const pldm_pdr_record* record{};
352 do
353 {
354 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
355 nullptr, nullptr);
356 if (record && pldm_pdr_record_is_remote(record))
357 {
358 changeEntries[0].push_back(
359 pldm_pdr_get_record_handle(repo, record));
360 }
361 } while (record);
362 }
363 if (changeEntries.empty())
364 {
365 return;
366 }
367 numsOfChangeEntries[0] = changeEntries[0].size();
368
369 // Encode PLDM platform event msg to indicate a PDR repo change.
370 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
371 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
372 changeEntries[0].size() * sizeof(uint32_t);
373 std::vector<uint8_t> eventDataVec{};
374 eventDataVec.resize(maxSize);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530375 auto eventData = new (eventDataVec.data())
376 pldm_pdr_repository_chg_event_data;
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500377 size_t actualSize{};
378 auto firstEntry = changeEntries[0].data();
379 auto rc = encode_pldm_pdr_repository_chg_event_data(
380 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
381 &firstEntry, eventData, &actualSize, maxSize);
382 if (rc != PLDM_SUCCESS)
383 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500384 error(
385 "Failed to encode pldm pdr repository change event data, response code '{RC}'",
386 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500387 return;
388 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930389 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400390 std::vector<uint8_t> requestMsg(
391 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
392 actualSize);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530393 auto request = new (requestMsg.data()) pldm_msg;
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500394 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600395 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
396 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500397 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500398 if (rc != PLDM_SUCCESS)
399 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930400 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500401 error(
402 "Failed to encode platform event message request, response code '{RC}'",
403 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500404 return;
405 }
406
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400407 auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/,
408 const pldm_msg* response,
409 size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700410 if (response == nullptr || !respMsgLen)
411 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600412 error(
413 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700414 return;
415 }
416
417 uint8_t completionCode{};
418 uint8_t status{};
419 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500420 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
421 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500422 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700423 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600424 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500425 "Failed to decode platform event message response, response code '{RC}' and completion code '{CC}'",
426 "RC", rc, "CC", completionCode);
Tom Joseph74f27c72021-05-16 07:58:53 -0700427 }
428 };
429
Sampa Misrac0c79482021-06-02 08:01:54 -0500430 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500431 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700432 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500433 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500434 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500435 error(
436 "Failed to send the PDR repository changed event request, response code '{RC}'",
437 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500438 }
439}
440
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530441void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500442{
443 for (const auto& pdr : stateSensorPDRs)
444 {
445 SensorEntry sensorEntry{};
446 const auto& [terminusHandle, sensorID, sensorInfo] =
447 responder::pdr_utils::parseStateSensorPDR(pdr);
448 sensorEntry.sensorID = sensorID;
449 try
450 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530451 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500452 }
453 // If there is no mapping for terminusHandle assign the reserved TID
454 // value of 0xFF to indicate that.
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500455 catch (const std::out_of_range&)
Sampa Misra868c8792020-05-26 03:12:13 -0500456 {
457 sensorEntry.terminusID = PLDM_TID_RESERVED;
458 }
459 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
460 }
461}
462
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400463void HostPDRHandler::processHostPDRs(
464 mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen)
Sampa Misrac0c79482021-06-02 08:01:54 -0500465{
466 static bool merged = false;
467 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800468 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500469 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600470 uint8_t tlEid = 0;
471 bool tlValid = true;
472 uint32_t rh = 0;
473 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530474 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600475 uint8_t tid = 0;
476
Sampa Misrac0c79482021-06-02 08:01:54 -0500477 uint8_t completionCode{};
478 uint32_t nextDataTransferHandle{};
479 uint8_t transferFlag{};
480 uint16_t respCount{};
481 uint8_t transferCRC{};
482 if (response == nullptr || !respMsgLen)
483 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600484 error("Failed to receive response for the GetPDR command");
Riya Dixit478e71d2024-06-21 14:10:14 -0500485 pldm::utils::reportError(
486 "xyz.openbmc_project.PLDM.Error.GetPDR.PDRExchangeFailure");
Sampa Misrac0c79482021-06-02 08:01:54 -0500487 return;
488 }
489
490 auto rc = decode_get_pdr_resp(
491 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
492 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
493 nullptr, 0, &transferCRC);
494 std::vector<uint8_t> responsePDRMsg;
495 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
496 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500497 if (rc != PLDM_SUCCESS)
498 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500499 error(
500 "Failed to decode getPDR response for next record handle '{NEXT_RECORD_HANDLE}', response code '{RC}'",
501 "NEXT_RECORD_HANDLE", nextRecordHandle, "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500502 return;
503 }
504 else
505 {
506 std::vector<uint8_t> pdr(respCount, 0);
507 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
508 &nextRecordHandle, &nextDataTransferHandle,
509 &transferFlag, &respCount, pdr.data(),
510 respCount, &transferCRC);
511 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
512 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500513 error(
514 "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}'",
515 "NEXT_RECORD_HANDLE", nextRecordHandle, "DATA_TRANSFER_HANDLE",
516 nextDataTransferHandle, "FLAG", transferFlag, "RC", rc, "CC",
517 completionCode);
Sampa Misrac0c79482021-06-02 08:01:54 -0500518 return;
519 }
520 else
521 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600522 // when nextRecordHandle is 0, we need the recordHandle of the last
523 // PDR and not 0-1.
524 if (!nextRecordHandle)
525 {
526 rh = nextRecordHandle;
527 }
528 else
529 {
530 rh = nextRecordHandle - 1;
531 }
532
Pavithra Barithaya49575832025-01-29 16:27:30 +0530533 auto pdrHdr = new (pdr.data()) pldm_pdr_hdr;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600534 if (!rh)
535 {
536 rh = pdrHdr->record_handle;
537 }
538
Sampa Misrac0c79482021-06-02 08:01:54 -0500539 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
540 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500541 this->mergeEntityAssociations(pdr, respCount, rh);
Sampa Misrac0c79482021-06-02 08:01:54 -0500542 merged = true;
543 }
544 else
545 {
546 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
547 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530548 pdrTerminusHandle =
549 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500550 auto tlpdr =
551 reinterpret_cast<const pldm_terminus_locator_pdr*>(
552 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600553
554 terminusHandle = tlpdr->terminus_handle;
555 tid = tlpdr->tid;
556 auto terminus_locator_type = tlpdr->terminus_locator_type;
557 if (terminus_locator_type ==
558 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
559 {
560 auto locatorValue = reinterpret_cast<
561 const pldm_terminus_locator_type_mctp_eid*>(
562 tlpdr->terminus_locator_value);
563 tlEid = static_cast<uint8_t>(locatorValue->eid);
564 }
565 if (tlpdr->validity == 0)
566 {
567 tlValid = false;
568 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500569 for (const auto& terminusMap : tlPDRInfo)
570 {
571 if ((terminusHandle == (terminusMap.first)) &&
572 (get<1>(terminusMap.second) == tlEid) &&
573 (get<2>(terminusMap.second) == tlpdr->validity))
574 {
575 // TL PDR already present with same validity don't
576 // add the PDR to the repo just return
577 return;
578 }
579 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530580 tlPDRInfo.insert_or_assign(
581 tlpdr->terminus_handle,
582 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500583 }
584 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
585 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530586 pdrTerminusHandle =
587 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800588 updateContainerId<pldm_state_sensor_pdr>(entityTree, pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500589 stateSensorPDRs.emplace_back(pdr);
590 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530591 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
592 {
593 pdrTerminusHandle =
594 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800595 updateContainerId<pldm_pdr_fru_record_set>(entityTree, pdr);
George Liu682ee182020-12-25 15:24:33 +0800596 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530597 }
598 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
599 {
600 pdrTerminusHandle =
601 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800602 updateContainerId<pldm_state_effecter_pdr>(entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530603 }
604 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
605 {
606 pdrTerminusHandle =
607 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
608 pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800609 updateContainerId<pldm_numeric_effecter_value_pdr>(
610 entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530611 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600612 // if the TLPDR is invalid update the repo accordingly
613 if (!tlValid)
614 {
615 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
616 tlValid);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500617
618 if (!isHostUp())
619 {
620 // The terminus PDR becomes invalid when the terminus
621 // itself is down. We don't need to do PDR exchange in
622 // that case, so setting the next record handle to 0.
623 nextRecordHandle = 0;
624 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600625 }
626 else
627 {
Andrew Jeffery5a945bd2024-08-01 13:15:36 +0000628 rc = pldm_pdr_add(repo, pdr.data(), respCount, true,
629 pdrTerminusHandle, &rh);
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930630 if (rc)
631 {
632 // pldm_pdr_add() assert()ed on failure to add a PDR.
633 throw std::runtime_error("Failed to add PDR");
634 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600635 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500636 }
637 }
638 }
639 if (!nextRecordHandle)
640 {
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500641 updateEntityAssociation(entityAssociations, entityTree, objPathMap,
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500642 entityMaps, oemPlatformHandler);
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -0500643 if (oemUtilsHandler)
644 {
645 oemUtilsHandler->setCoreCount(entityAssociations, entityMaps);
646 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500647 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530648 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800649 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600650 if (isHostUp())
651 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530652 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600653 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500654 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800655 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800656 entityAssociations.clear();
657
Sampa Misrac0c79482021-06-02 08:01:54 -0500658 if (merged)
659 {
660 merged = false;
661 deferredPDRRepoChgEvent =
662 std::make_unique<sdeventplus::source::Defer>(
663 event,
664 std::bind(
665 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
666 this, std::placeholders::_1));
667 }
668 }
669 else
670 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500671 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
672 {
673 isHostPdrModified = false;
674 }
675 else
676 {
677 deferredFetchPDREvent =
678 std::make_unique<sdeventplus::source::Defer>(
679 event,
680 std::bind(
681 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
682 this, nextRecordHandle, std::placeholders::_1));
683 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500684 }
685}
686
687void HostPDRHandler::_processPDRRepoChgEvent(
688 sdeventplus::source::EventBase& /*source */)
689{
690 deferredPDRRepoChgEvent.reset();
691 this->sendPDRRepositoryChgEvent(
Andrew Jefferyc14fb4b2024-07-25 22:13:09 +0930692 std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION),
Sampa Misrac0c79482021-06-02 08:01:54 -0500693 FORMAT_IS_PDR_HANDLES);
694}
695
696void HostPDRHandler::_processFetchPDREvent(
697 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
698{
699 deferredFetchPDREvent.reset();
700 if (!this->pdrRecordHandles.empty())
701 {
702 nextRecordHandle = this->pdrRecordHandles.front();
703 this->pdrRecordHandles.pop_front();
704 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500705 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
706 {
707 nextRecordHandle = this->modifiedPDRRecordHandles.front();
708 this->modifiedPDRRecordHandles.pop_front();
709 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500710 this->getHostPDR(nextRecordHandle);
711}
712
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500713void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530714{
sampmisr6decfc12021-03-02 11:07:36 +0530715 responseReceived = false;
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930716 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400717 std::vector<uint8_t> requestMsg(
718 sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530719 auto request = new (requestMsg.data()) pldm_msg;
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500720 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
721 PLDM_BASE, request);
722 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530723 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500724 error("Failed to encode GetPLDMVersion, response code {RC}", "RC",
Riya Dixit49cfb132023-03-02 04:26:53 -0600725 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930726 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530727 return;
728 }
729
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500730 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
731 const pldm_msg* response,
732 size_t respMsgLen) {
733 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530734 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600735 error(
736 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530737 return;
738 }
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500739 info("Getting the response code '{RC}'", "RC", lg2::hex,
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500740 response->payload[0]);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500741 this->responseReceived = true;
sampmisr6decfc12021-03-02 11:07:36 +0530742 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500743 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
744 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
745 std::move(getPLDMVersionHandler));
746 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530747 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500748 error(
749 "Failed to discover remote terminus state. Assuming remote terminus as off");
sampmisr6decfc12021-03-02 11:07:36 +0530750 }
751}
752
753bool HostPDRHandler::isHostUp()
754{
755 return responseReceived;
756}
757
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530758void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600759{
760 for (const auto& stateSensorPDR : stateSensorPDRs)
761 {
762 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
763 stateSensorPDR.data());
764
765 if (!pdr)
766 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500767 error("Failed to get state sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600768 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530769 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600770 return;
771 }
772
773 uint16_t sensorId = pdr->sensor_id;
774
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530775 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600776 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530777 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600778 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530779 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600780 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530781 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600782 }
783
784 bitfield8_t sensorRearm;
785 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530786 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600787
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930788 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600789 std::vector<uint8_t> requestMsg(
790 sizeof(pldm_msg_hdr) +
791 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530792 auto request = new (requestMsg.data()) pldm_msg;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600793 auto rc = encode_get_state_sensor_readings_req(
794 instanceId, sensorId, sensorRearm, 0, request);
795
796 if (rc != PLDM_SUCCESS)
797 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930798 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600799 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500800 "Failed to encode get state sensor readings request for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
801 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
802 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600803 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530804 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600805 return;
806 }
807
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400808 auto getStateSensorReadingRespHandler = [=, this](
809 mctp_eid_t /*eid*/,
810 const pldm_msg*
811 response,
812 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600813 if (response == nullptr || !respMsgLen)
814 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600815 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500816 "Failed to receive response for get state sensor reading command for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}'",
817 "SENSOR_ID", sensorId, "INSTANCE", instanceId);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600818 return;
819 }
820 std::array<get_sensor_state_field, 8> stateField{};
821 uint8_t completionCode = 0;
822 uint8_t comp_sensor_count = 0;
823
824 auto rc = decode_get_state_sensor_readings_resp(
825 response, respMsgLen, &completionCode,
826 &comp_sensor_count, stateField.data());
827
828 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
829 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600830 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500831 "Failed to decode get state sensor readings response for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code'{RC}' and completion code '{CC}'",
832 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
833 rc, "CC", completionCode);
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530834 pldm::utils::reportError(
835 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600836 }
837
838 uint8_t eventState;
839 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600840
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500841 for (uint8_t sensorOffset = 0;
842 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600843 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500844 eventState = stateField[sensorOffset].present_state;
845 previousEventState =
846 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600847
848 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
849 eventState,
850 previousEventState);
851
852 SensorEntry sensorEntry{tid, sensorId};
853
854 pldm::pdr::EntityInfo entityInfo{};
855 pldm::pdr::CompositeSensorStates
856 compositeSensorStates{};
Sagar Srinivase3607a32024-02-16 03:50:53 -0600857 std::vector<pldm::pdr::StateSetId> stateSetIds{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600858
859 try
860 {
Sagar Srinivase3607a32024-02-16 03:50:53 -0600861 std::tie(entityInfo, compositeSensorStates,
862 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600863 lookupSensorInfo(sensorEntry);
864 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500865 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600866 {
867 try
868 {
869 sensorEntry.terminusID = PLDM_TID_RESERVED;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600870 std::tie(entityInfo, compositeSensorStates,
871 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600872 lookupSensorInfo(sensorEntry);
873 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500874 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600875 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600876 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600877 }
878 }
879
Manojkiran Eda07a07e22024-04-24 19:15:10 +0530880 if ((compositeSensorStates.size() > 1) &&
881 (sensorOffset > (compositeSensorStates.size() - 1)))
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600882 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500883 error(
884 "Error Invalid data, Invalid sensor offset '{SENSOR_OFFSET}'",
885 "SENSOR_OFFSET", sensorOffset);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600886 return;
887 }
888
889 const auto& possibleStates =
890 compositeSensorStates[sensorOffset];
891 if (possibleStates.find(eventState) ==
892 possibleStates.end())
893 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500894 error(
895 "Error invalid_data, Invalid event state '{STATE}'",
896 "STATE", eventState);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600897 return;
898 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400899 const auto& [containerId, entityType, entityInstance] =
900 entityInfo;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600901 auto stateSetId = stateSetIds[sensorOffset];
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600902 pldm::responder::events::StateSensorEntry
Manojkiran Edafa084702024-05-27 10:20:30 +0530903 stateSensorEntry{containerId, entityType,
Sagar Srinivase3607a32024-02-16 03:50:53 -0600904 entityInstance, sensorOffset,
Manojkiran Edafa084702024-05-27 10:20:30 +0530905 stateSetId, false};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600906 handleStateSensorEvent(stateSensorEntry, eventState);
907 }
908 };
909
910 rc = handler->registerRequest(
911 mctp_eid, instanceId, PLDM_PLATFORM,
912 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg),
913 std::move(getStateSensorReadingRespHandler));
914
915 if (rc != PLDM_SUCCESS)
916 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600917 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500918 "Failed to send request to get state sensor reading on remote terminus for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
919 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
920 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600921 }
922 }
923 }
924 }
925}
George Liu682ee182020-12-25 15:24:33 +0800926
927void HostPDRHandler::getFRURecordTableMetadataByRemote(
928 const PDRList& fruRecordSetPDRs)
929{
930 auto instanceId = instanceIdDb.next(mctp_eid);
931 std::vector<uint8_t> requestMsg(
932 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
933
934 // GetFruRecordTableMetadata
Pavithra Barithaya49575832025-01-29 16:27:30 +0530935 auto request = new (requestMsg.data()) pldm_msg;
George Liu682ee182020-12-25 15:24:33 +0800936 auto rc = encode_get_fru_record_table_metadata_req(
937 instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
938 if (rc != PLDM_SUCCESS)
939 {
940 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500941 error(
942 "Failed to encode get fru record table metadata request, response code '{RC}'",
George Liu682ee182020-12-25 15:24:33 +0800943 "RC", lg2::hex, rc);
944 return;
945 }
946
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400947 auto getFruRecordTableMetadataResponseHandler = [this, fruRecordSetPDRs](
948 mctp_eid_t /*eid*/,
949 const pldm_msg*
950 response,
951 size_t respMsgLen) {
George Liu682ee182020-12-25 15:24:33 +0800952 if (response == nullptr || !respMsgLen)
953 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500954 error(
955 "Failed to receive response for the get fru record table metadata");
George Liu682ee182020-12-25 15:24:33 +0800956 return;
957 }
958
959 uint8_t cc = 0;
960 uint8_t fru_data_major_version, fru_data_minor_version;
961 uint32_t fru_table_maximum_size, fru_table_length;
962 uint16_t total_record_set_identifiers;
963 uint16_t total;
964 uint32_t checksum;
965
966 auto rc = decode_get_fru_record_table_metadata_resp(
967 response, respMsgLen, &cc, &fru_data_major_version,
968 &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
969 &total_record_set_identifiers, &total, &checksum);
970
971 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
972 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500973 error(
974 "Failed to decode get fru record table metadata response, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +0800975 "RC", lg2::hex, rc, "CC", cc);
976 return;
977 }
978
979 // pass total to getFRURecordTableByRemote
980 this->getFRURecordTableByRemote(fruRecordSetPDRs, total);
981 };
982
983 rc = handler->registerRequest(
984 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA,
985 std::move(requestMsg),
986 std::move(getFruRecordTableMetadataResponseHandler));
987 if (rc != PLDM_SUCCESS)
988 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500989 error(
990 "Failed to send the the set state effecter states request, response code '{RC}'",
991 "RC", rc);
George Liu682ee182020-12-25 15:24:33 +0800992 }
993
994 return;
995}
996
997void HostPDRHandler::getFRURecordTableByRemote(const PDRList& fruRecordSetPDRs,
998 uint16_t totalTableRecords)
999{
1000 fruRecordData.clear();
1001
1002 if (!totalTableRecords)
1003 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001004 error("Failed to get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001005 return;
1006 }
1007
1008 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001009 std::vector<uint8_t> requestMsg(
1010 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
George Liu682ee182020-12-25 15:24:33 +08001011
1012 // send the getFruRecordTable command
Pavithra Barithaya49575832025-01-29 16:27:30 +05301013 auto request = new (requestMsg.data()) pldm_msg;
George Liu682ee182020-12-25 15:24:33 +08001014 auto rc = encode_get_fru_record_table_req(
1015 instanceId, 0, PLDM_GET_FIRSTPART, request,
1016 requestMsg.size() - sizeof(pldm_msg_hdr));
1017 if (rc != PLDM_SUCCESS)
1018 {
1019 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001020 error(
1021 "Failed to encode get fru record table request, response code '{RC}'",
1022 "RC", lg2::hex, rc);
George Liu682ee182020-12-25 15:24:33 +08001023 return;
1024 }
1025
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001026 auto getFruRecordTableResponseHandler = [totalTableRecords, this,
1027 fruRecordSetPDRs](
1028 mctp_eid_t /*eid*/,
1029 const pldm_msg* response,
1030 size_t respMsgLen) {
George Liu682ee182020-12-25 15:24:33 +08001031 if (response == nullptr || !respMsgLen)
1032 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001033 error("Failed to receive response for the get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001034 return;
1035 }
1036
1037 uint8_t cc = 0;
1038 uint32_t next_data_transfer_handle = 0;
1039 uint8_t transfer_flag = 0;
1040 size_t fru_record_table_length = 0;
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001041 std::vector<uint8_t> fru_record_table_data(
1042 respMsgLen - sizeof(pldm_msg_hdr));
George Liu682ee182020-12-25 15:24:33 +08001043 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
1044 auto rc = decode_get_fru_record_table_resp(
Manojkiran Eda33a9cd02024-01-22 11:06:59 +05301045 responsePtr, respMsgLen, &cc, &next_data_transfer_handle,
1046 &transfer_flag, fru_record_table_data.data(),
1047 &fru_record_table_length);
George Liu682ee182020-12-25 15:24:33 +08001048
1049 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
1050 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001051 error(
1052 "Failed to decode get fru record table resp, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +08001053 "RC", lg2::hex, rc, "CC", cc);
1054 return;
1055 }
1056
1057 fruRecordData = responder::pdr_utils::parseFruRecordTable(
1058 fru_record_table_data.data(), fru_record_table_length);
1059
1060 if (totalTableRecords != fruRecordData.size())
1061 {
1062 fruRecordData.clear();
1063
Manojkiran Eda2576aec2024-06-17 12:05:17 +05301064 error("Failed to parse fru record data format.");
George Liu682ee182020-12-25 15:24:33 +08001065 return;
1066 }
1067
1068 this->setFRUDataOnDBus(fruRecordSetPDRs, fruRecordData);
1069 };
1070
1071 rc = handler->registerRequest(
1072 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE,
1073 std::move(requestMsg), std::move(getFruRecordTableResponseHandler));
1074 if (rc != PLDM_SUCCESS)
1075 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001076 error("Failed to send the the set state effecter states request");
George Liu682ee182020-12-25 15:24:33 +08001077 }
1078}
1079
1080std::optional<uint16_t> HostPDRHandler::getRSI(const PDRList& fruRecordSetPDRs,
1081 const pldm_entity& entity)
1082{
1083 for (const auto& pdr : fruRecordSetPDRs)
1084 {
1085 auto fruPdr = reinterpret_cast<const pldm_pdr_fru_record_set*>(
1086 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
1087
1088 if (fruPdr->entity_type == entity.entity_type &&
Sagar Srinivasebf8bb52023-10-06 01:15:55 -05001089 fruPdr->entity_instance == entity.entity_instance_num &&
1090 fruPdr->container_id == entity.entity_container_id)
George Liu682ee182020-12-25 15:24:33 +08001091 {
1092 return fruPdr->fru_rsi;
1093 }
1094 }
1095
1096 return std::nullopt;
1097}
1098
1099void HostPDRHandler::setFRUDataOnDBus(
Patrick Williamsd310f822023-10-07 19:01:19 -05001100 [[maybe_unused]] const PDRList& fruRecordSetPDRs,
1101 [[maybe_unused]] const std::vector<
1102 responder::pdr_utils::FruRecordDataFormat>& fruRecordData)
George Liu682ee182020-12-25 15:24:33 +08001103{
Patrick Williamsd310f822023-10-07 19:01:19 -05001104#ifdef OEM_IBM
George Liu682ee182020-12-25 15:24:33 +08001105 for (const auto& entity : objPathMap)
1106 {
1107 pldm_entity node = pldm_entity_extract(entity.second);
1108 auto fruRSI = getRSI(fruRecordSetPDRs, node);
1109
1110 for (const auto& data : fruRecordData)
1111 {
1112 if (!fruRSI || *fruRSI != data.fruRSI)
1113 {
1114 continue;
1115 }
1116
1117 if (data.fruRecType == PLDM_FRU_RECORD_TYPE_OEM)
1118 {
1119 for (const auto& tlv : data.fruTLV)
1120 {
1121 if (tlv.fruFieldType ==
1122 PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE)
1123 {
1124 CustomDBus::getCustomDBus().setLocationCode(
1125 entity.first,
1126 std::string(reinterpret_cast<const char*>(
1127 tlv.fruFieldValue.data()),
1128 tlv.fruFieldLen));
1129 }
1130 }
1131 }
1132 }
1133 }
Patrick Williamsd310f822023-10-07 19:01:19 -05001134#endif
George Liu682ee182020-12-25 15:24:33 +08001135}
Archana Kakanif9355372025-02-04 03:13:24 -06001136
Archana Kakanic3664472025-02-04 05:36:37 -06001137void HostPDRHandler::setPresentPropertyStatus(const std::string& path)
1138{
1139 CustomDBus::getCustomDBus().updateItemPresentStatus(path, true);
1140}
1141
Archana Kakanif9355372025-02-04 03:13:24 -06001142void HostPDRHandler::setAvailabilityState(const std::string& path)
1143{
1144 CustomDBus::getCustomDBus().setAvailabilityState(path, true);
1145}
1146
George Liu682ee182020-12-25 15:24:33 +08001147void HostPDRHandler::createDbusObjects(const PDRList& fruRecordSetPDRs)
1148{
Archana Kakanif9355372025-02-04 03:13:24 -06001149 // Creating and Refreshing dbus hosted by remote PLDM entity Fru PDRs
1150
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001151 for (const auto& entity : objPathMap)
1152 {
Archana Kakanic3664472025-02-04 05:36:37 -06001153 // update the Present Property
1154 setPresentPropertyStatus(entity.first);
Archana Kakanif9355372025-02-04 03:13:24 -06001155 // Implement & update the Availability to true
1156 setAvailabilityState(entity.first);
1157
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001158 pldm_entity node = pldm_entity_extract(entity.second);
1159 switch (node.entity_type)
1160 {
1161 case PLDM_ENTITY_PROC | 0x8000:
1162 CustomDBus::getCustomDBus().implementCpuCoreInterface(
1163 entity.first);
1164 break;
Archana Kakanidb65c3b2025-02-03 05:27:28 -06001165 case PLDM_ENTITY_SYSTEM_CHASSIS:
1166 CustomDBus::getCustomDBus().implementChassisInterface(
1167 entity.first);
1168 break;
Archana Kakani24e9a9b2025-02-04 00:27:25 -06001169 case PLDM_ENTITY_POWER_SUPPLY:
1170 CustomDBus::getCustomDBus().implementPowerSupplyInterface(
1171 entity.first);
1172 break;
Archana Kakani765cf032025-02-04 06:24:14 -06001173 case PLDM_ENTITY_CHASSIS_FRONT_PANEL_BOARD:
1174 CustomDBus::getCustomDBus().implementPanelInterface(
1175 entity.first);
1176 break;
Archana Kakani2832f2c2025-02-04 22:29:30 -06001177 case PLDM_ENTITY_POWER_CONVERTER:
1178 CustomDBus::getCustomDBus().implementVRMInterface(entity.first);
1179 break;
Archana Kakanibf1fd272024-06-05 13:25:53 -05001180 case PLDM_ENTITY_SLOT:
1181 CustomDBus::getCustomDBus().implementPCIeSlotInterface(
1182 entity.first);
1183 break;
Archana Kakani17b1e8a2025-02-04 03:50:24 -06001184 case PLDM_ENTITY_CONNECTOR:
1185 CustomDBus::getCustomDBus().implementConnecterInterface(
1186 entity.first);
1187 break;
Archana Kakanid432b482025-02-04 22:52:28 -06001188 case PLDM_ENTITY_BOARD:
1189 CustomDBus::getCustomDBus().implementBoard(entity.first);
1190 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001191 case PLDM_ENTITY_CARD:
1192 CustomDBus::getCustomDBus().implementPCIeDeviceInterface(
1193 entity.first);
1194 break;
Kamalkumar Patel2ed986c2024-05-08 02:20:47 -05001195 case PLDM_ENTITY_SYS_BOARD:
1196 CustomDBus::getCustomDBus().implementMotherboardInterface(
1197 entity.first);
1198 break;
Archana Kakani413f51e2025-02-03 04:14:36 -06001199 case PLDM_ENTITY_FAN:
1200 CustomDBus::getCustomDBus().implementFanInterface(entity.first);
1201 break;
Archana Kakani42876b62025-02-04 04:22:29 -06001202 case PLDM_ENTITY_IO_MODULE:
1203 CustomDBus::getCustomDBus().implementFabricAdapter(
1204 entity.first);
1205 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001206 default:
1207 break;
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001208 }
1209 }
George Liu682ee182020-12-25 15:24:33 +08001210 getFRURecordTableMetadataByRemote(fruRecordSetPDRs);
1211}
1212
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001213} // namespace pldm