blob: 4bcdb7c739399670a6475756a15bbf68959ff0aa [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
Pavithra Barithayae8beb892020-04-14 23:24:25 -05009#include <assert.h>
10
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050011#include <nlohmann/json.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060012#include <phosphor-logging/lg2.hpp>
sampmisr6decfc12021-03-02 11:07:36 +053013#include <sdeventplus/clock.hpp>
14#include <sdeventplus/exception.hpp>
15#include <sdeventplus/source/io.hpp>
16#include <sdeventplus/source/time.hpp>
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050017
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
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050023namespace pldm
24{
Brad Bishop5079ac42021-08-19 18:35:06 -040025using namespace pldm::responder::events;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -050026using namespace pldm::utils;
27using namespace sdbusplus::bus::match::rules;
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050028using namespace pldm::responder::pdr_utils;
Kamalkumar Patel516122e2024-05-07 04:39:32 -050029using namespace pldm::hostbmc::utils;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050030using Json = nlohmann::json;
31namespace fs = std::filesystem;
George Liu682ee182020-12-25 15:24:33 +080032using namespace pldm::dbus;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050033const Json emptyJson{};
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050034
Manojkiran Eda3ca40452021-10-04 22:51:37 +053035template <typename T>
36uint16_t extractTerminusHandle(std::vector<uint8_t>& pdr)
37{
38 T* var = nullptr;
39 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
40 {
41 var = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
42 }
43 else
44 {
45 var = (T*)(pdr.data());
46 }
47 if (var != nullptr)
48 {
49 return var->terminus_handle;
50 }
51 return TERMINUS_HANDLE;
52}
53
George Liu96af8cb2021-07-31 15:23:45 +080054template <typename T>
55void updateContainerId(pldm_entity_association_tree* entityTree,
56 std::vector<uint8_t>& pdr)
57{
58 T* t = nullptr;
59 if (entityTree == nullptr)
60 {
61 return;
62 }
63 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
64 {
65 t = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
66 }
67 else
68 {
69 t = (T*)(pdr.data());
70 }
71 if (t == nullptr)
72 {
73 return;
74 }
75
76 pldm_entity entity{t->entity_type, t->entity_instance, t->container_id};
Patrick Williams16c2a0a2024-08-16 15:20:59 -040077 auto node = pldm_entity_association_tree_find_with_locality(
78 entityTree, &entity, true);
George Liu96af8cb2021-07-31 15:23:45 +080079 if (node)
80 {
81 pldm_entity e = pldm_entity_extract(node);
82 t->container_id = e.entity_container_id;
83 }
84}
85
Tom Joseph74f27c72021-05-16 07:58:53 -070086HostPDRHandler::HostPDRHandler(
Andrew Jeffery3dd444d2024-07-25 22:00:27 +093087 int /* mctp_fd */, uint8_t mctp_eid, sdeventplus::Event& event,
88 pldm_pdr* repo, const std::string& eventsJsonsDir,
89 pldm_entity_association_tree* entityTree,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093090 pldm_entity_association_tree* bmcEntityTree,
91 pldm::InstanceIdDb& instanceIdDb,
George Liua881c172021-06-21 18:28:11 +080092 pldm::requester::Handler<pldm::requester::Request>* handler) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040093 mctp_eid(mctp_eid), event(event), repo(repo),
94 stateSensorHandler(eventsJsonsDir), entityTree(entityTree),
95 instanceIdDb(instanceIdDb), handler(handler),
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -050096 entityMaps(parseEntityMap(ENTITY_MAP_JSON)), oemUtilsHandler(nullptr)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050097{
George Liuacf2c8c2021-05-10 14:08:52 +080098 mergedHostParents = false;
Patrick Williams84b790c2022-07-22 19:26:56 -050099 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500100 pldm::utils::DBusHandler::getBus(),
101 propertiesChanged("/xyz/openbmc_project/state/host0",
102 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -0500103 [this, repo, entityTree, bmcEntityTree](sdbusplus::message_t& msg) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400104 DbusChangedProps props{};
105 std::string intf;
106 msg.read(intf, props);
107 const auto itr = props.find("CurrentHostState");
108 if (itr != props.end())
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500109 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400110 PropertyValue value = itr->second;
111 auto propVal = std::get<std::string>(value);
112 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
113 {
114 // Delete all the remote terminus information
115 std::erase_if(tlPDRInfo, [](const auto& item) {
116 const auto& [key, value] = item;
117 return key != TERMINUS_HANDLE;
118 });
119 pldm_pdr_remove_remote_pdrs(repo);
120 pldm_entity_association_tree_destroy_root(entityTree);
121 pldm_entity_association_tree_copy_root(bmcEntityTree,
122 entityTree);
123 this->sensorMap.clear();
124 this->responseReceived = false;
125 this->mergedHostParents = false;
126 }
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500127 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400128 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500129}
130
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500131void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500132{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500133 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500134 modifiedPDRRecordHandles.clear();
135
136 if (isHostPdrModified)
137 {
138 modifiedPDRRecordHandles = std::move(recordHandles);
139 }
140 else
141 {
142 pdrRecordHandles = std::move(recordHandles);
143 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500144
145 // Defer the actual fetch of PDRs from the host (by queuing the call on the
146 // main event loop). That way, we can respond to the platform event msg from
147 // the host firmware.
148 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
149 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
150 std::placeholders::_1));
151}
152
153void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
154{
Sampa Misrac0c79482021-06-02 08:01:54 -0500155 getHostPDR();
156}
157
158void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
159{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500160 pdrFetchEvent.reset();
161
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400162 std::vector<uint8_t> requestMsg(
163 sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES);
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500164 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500165 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500166 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
167 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500168 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500169 recordHandle = modifiedPDRRecordHandles.front();
170 modifiedPDRRecordHandles.pop_front();
171 }
172 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
173 {
174 recordHandle = pdrRecordHandles.front();
175 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500176 }
177 else
178 {
179 recordHandle = nextRecordHandle;
180 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930181 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500182
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400183 auto rc =
184 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
185 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500186 if (rc != PLDM_SUCCESS)
187 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930188 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500189 error("Failed to encode get pdr request, response code '{RC}'", "RC",
190 rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500191 return;
192 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500193
Sampa Misrac0c79482021-06-02 08:01:54 -0500194 rc = handler->registerRequest(
195 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
196 std::move(requestMsg),
Andrew Jefferyc14fb4b2024-07-25 22:13:09 +0930197 std::bind_front(&HostPDRHandler::processHostPDRs, this));
Sampa Misrac0c79482021-06-02 08:01:54 -0500198 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500199 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500200 error(
201 "Failed to send the getPDR request to remote terminus, response code '{RC}'",
202 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500203 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500204}
205
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600206int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
207 pdr::EventState state)
208{
209 auto rc = stateSensorHandler.eventAction(entry, state);
210 if (rc != PLDM_SUCCESS)
211 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500212 error("Failed to fetch and update D-bus property, response code '{RC}'",
213 "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600214 return rc;
215 }
216 return PLDM_SUCCESS;
217}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500218
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500219void HostPDRHandler::mergeEntityAssociations(
220 const std::vector<uint8_t>& pdr, [[maybe_unused]] const uint32_t& size,
221 [[maybe_unused]] const uint32_t& record_handle)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500222{
223 size_t numEntities{};
224 pldm_entity* entities = nullptr;
225 bool merged = false;
226 auto entityPdr = reinterpret_cast<pldm_pdr_entity_association*>(
227 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
228
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500229 if (oemPlatformHandler &&
230 oemPlatformHandler->checkRecordHandleInRange(record_handle))
231 {
232 // Adding the remote range PDRs to the repo before merging it
233 uint32_t handle = record_handle;
Andrew Jeffery5a945bd2024-08-01 13:15:36 +0000234 pldm_pdr_add(repo, pdr.data(), size, true, 0xFFFF, &handle);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500235 }
236
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500237 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
238 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800239 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500240 {
George Liuacf2c8c2021-05-10 14:08:52 +0800241 pldm_entity_node* pNode = nullptr;
242 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500243 {
George Liuacf2c8c2021-05-10 14:08:52 +0800244 pNode = pldm_entity_association_tree_find_with_locality(
245 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500246 }
George Liuacf2c8c2021-05-10 14:08:52 +0800247 else
248 {
249 pNode = pldm_entity_association_tree_find_with_locality(
250 entityTree, &entities[0], true);
251 }
252 if (!pNode)
253 {
254 return;
255 }
256
George Liudf9a6d32020-12-22 16:27:16 +0800257 Entities entityAssoc;
258 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800259 for (size_t i = 1; i < numEntities; ++i)
260 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500261 bool isUpdateContainerId = true;
262 if (oemPlatformHandler)
263 {
264 isUpdateContainerId =
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600265 checkIfLogicalBitSet(entities[i].entity_container_id);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500266 }
George Liudf9a6d32020-12-22 16:27:16 +0800267 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800268 entityTree, &entities[i], entities[i].entity_instance_num,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500269 pNode, entityPdr->association_type, true, isUpdateContainerId,
270 0xFFFF);
271 if (!node)
272 {
273 continue;
274 }
George Liuacf2c8c2021-05-10 14:08:52 +0800275 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800276 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800277 }
278
279 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800280 if (merged)
281 {
282 entityAssociations.push_back(entityAssoc);
283 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500284 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500285
286 if (merged)
287 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500288 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500289 pldm_entity_node* node = nullptr;
290 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
291 if (node == nullptr)
292 {
Manojkiran Eda2576aec2024-06-17 12:05:17 +0530293 error("Failed to find reference of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500294 }
295 else
296 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500297 int rc = 0;
298 if (oemPlatformHandler)
299 {
300 auto record = oemPlatformHandler->fetchLastBMCRecord(repo);
301
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400302 uint32_t record_handle =
303 pldm_pdr_get_record_handle(repo, record);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500304
305 rc =
306 pldm_entity_association_pdr_add_from_node_with_record_handle(
307 node, repo, &entities, numEntities, true,
308 TERMINUS_HANDLE, (record_handle + 1));
309 }
310 else
311 {
Andrew Jeffery7761bd22024-08-01 13:15:36 +0000312 rc = pldm_entity_association_pdr_add_from_node(
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500313 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
314 }
315
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930316 if (rc)
317 {
318 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500319 "Failed to add entity association PDR from node, response code '{RC}'",
320 "RC", rc);
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930321 }
Sampa Misra719ed392021-06-04 05:15:13 -0500322 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500323 }
Sampa Misra719ed392021-06-04 05:15:13 -0500324 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500325}
326
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500327void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
328 uint8_t eventDataFormat)
329{
330 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
331
332 // Extract from the PDR repo record handles of PDRs we want the host
333 // to pull up.
334 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
335 std::vector<uint8_t> numsOfChangeEntries(1);
336 std::vector<std::vector<ChangeEntry>> changeEntries(
337 numsOfChangeEntries.size());
338 for (auto pdrType : pdrTypes)
339 {
340 const pldm_pdr_record* record{};
341 do
342 {
343 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
344 nullptr, nullptr);
345 if (record && pldm_pdr_record_is_remote(record))
346 {
347 changeEntries[0].push_back(
348 pldm_pdr_get_record_handle(repo, record));
349 }
350 } while (record);
351 }
352 if (changeEntries.empty())
353 {
354 return;
355 }
356 numsOfChangeEntries[0] = changeEntries[0].size();
357
358 // Encode PLDM platform event msg to indicate a PDR repo change.
359 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
360 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
361 changeEntries[0].size() * sizeof(uint32_t);
362 std::vector<uint8_t> eventDataVec{};
363 eventDataVec.resize(maxSize);
364 auto eventData =
365 reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
366 eventDataVec.data());
367 size_t actualSize{};
368 auto firstEntry = changeEntries[0].data();
369 auto rc = encode_pldm_pdr_repository_chg_event_data(
370 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
371 &firstEntry, eventData, &actualSize, maxSize);
372 if (rc != PLDM_SUCCESS)
373 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500374 error(
375 "Failed to encode pldm pdr repository change event data, response code '{RC}'",
376 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500377 return;
378 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930379 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400380 std::vector<uint8_t> requestMsg(
381 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
382 actualSize);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500383 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
384 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600385 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
386 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500387 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500388 if (rc != PLDM_SUCCESS)
389 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930390 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500391 error(
392 "Failed to encode platform event message request, response code '{RC}'",
393 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500394 return;
395 }
396
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400397 auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/,
398 const pldm_msg* response,
399 size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700400 if (response == nullptr || !respMsgLen)
401 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600402 error(
403 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700404 return;
405 }
406
407 uint8_t completionCode{};
408 uint8_t status{};
409 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500410 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
411 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500412 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700413 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600414 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500415 "Failed to decode platform event message response, response code '{RC}' and completion code '{CC}'",
416 "RC", rc, "CC", completionCode);
Tom Joseph74f27c72021-05-16 07:58:53 -0700417 }
418 };
419
Sampa Misrac0c79482021-06-02 08:01:54 -0500420 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500421 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700422 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500423 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500424 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500425 error(
426 "Failed to send the PDR repository changed event request, response code '{RC}'",
427 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500428 }
429}
430
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530431void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500432{
433 for (const auto& pdr : stateSensorPDRs)
434 {
435 SensorEntry sensorEntry{};
436 const auto& [terminusHandle, sensorID, sensorInfo] =
437 responder::pdr_utils::parseStateSensorPDR(pdr);
438 sensorEntry.sensorID = sensorID;
439 try
440 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530441 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500442 }
443 // If there is no mapping for terminusHandle assign the reserved TID
444 // value of 0xFF to indicate that.
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500445 catch (const std::out_of_range&)
Sampa Misra868c8792020-05-26 03:12:13 -0500446 {
447 sensorEntry.terminusID = PLDM_TID_RESERVED;
448 }
449 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
450 }
451}
452
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400453void HostPDRHandler::processHostPDRs(
454 mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen)
Sampa Misrac0c79482021-06-02 08:01:54 -0500455{
456 static bool merged = false;
457 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800458 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500459 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600460 uint8_t tlEid = 0;
461 bool tlValid = true;
462 uint32_t rh = 0;
463 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530464 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600465 uint8_t tid = 0;
466
Sampa Misrac0c79482021-06-02 08:01:54 -0500467 uint8_t completionCode{};
468 uint32_t nextDataTransferHandle{};
469 uint8_t transferFlag{};
470 uint16_t respCount{};
471 uint8_t transferCRC{};
472 if (response == nullptr || !respMsgLen)
473 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600474 error("Failed to receive response for the GetPDR command");
Riya Dixit478e71d2024-06-21 14:10:14 -0500475 pldm::utils::reportError(
476 "xyz.openbmc_project.PLDM.Error.GetPDR.PDRExchangeFailure");
Sampa Misrac0c79482021-06-02 08:01:54 -0500477 return;
478 }
479
480 auto rc = decode_get_pdr_resp(
481 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
482 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
483 nullptr, 0, &transferCRC);
484 std::vector<uint8_t> responsePDRMsg;
485 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
486 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500487 if (rc != PLDM_SUCCESS)
488 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500489 error(
490 "Failed to decode getPDR response for next record handle '{NEXT_RECORD_HANDLE}', response code '{RC}'",
491 "NEXT_RECORD_HANDLE", nextRecordHandle, "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500492 return;
493 }
494 else
495 {
496 std::vector<uint8_t> pdr(respCount, 0);
497 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
498 &nextRecordHandle, &nextDataTransferHandle,
499 &transferFlag, &respCount, pdr.data(),
500 respCount, &transferCRC);
501 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
502 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500503 error(
504 "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}'",
505 "NEXT_RECORD_HANDLE", nextRecordHandle, "DATA_TRANSFER_HANDLE",
506 nextDataTransferHandle, "FLAG", transferFlag, "RC", rc, "CC",
507 completionCode);
Sampa Misrac0c79482021-06-02 08:01:54 -0500508 return;
509 }
510 else
511 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600512 // when nextRecordHandle is 0, we need the recordHandle of the last
513 // PDR and not 0-1.
514 if (!nextRecordHandle)
515 {
516 rh = nextRecordHandle;
517 }
518 else
519 {
520 rh = nextRecordHandle - 1;
521 }
522
Sampa Misrac0c79482021-06-02 08:01:54 -0500523 auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600524 if (!rh)
525 {
526 rh = pdrHdr->record_handle;
527 }
528
Sampa Misrac0c79482021-06-02 08:01:54 -0500529 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
530 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500531 this->mergeEntityAssociations(pdr, respCount, rh);
Sampa Misrac0c79482021-06-02 08:01:54 -0500532 merged = true;
533 }
534 else
535 {
536 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
537 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530538 pdrTerminusHandle =
539 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500540 auto tlpdr =
541 reinterpret_cast<const pldm_terminus_locator_pdr*>(
542 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600543
544 terminusHandle = tlpdr->terminus_handle;
545 tid = tlpdr->tid;
546 auto terminus_locator_type = tlpdr->terminus_locator_type;
547 if (terminus_locator_type ==
548 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
549 {
550 auto locatorValue = reinterpret_cast<
551 const pldm_terminus_locator_type_mctp_eid*>(
552 tlpdr->terminus_locator_value);
553 tlEid = static_cast<uint8_t>(locatorValue->eid);
554 }
555 if (tlpdr->validity == 0)
556 {
557 tlValid = false;
558 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500559 for (const auto& terminusMap : tlPDRInfo)
560 {
561 if ((terminusHandle == (terminusMap.first)) &&
562 (get<1>(terminusMap.second) == tlEid) &&
563 (get<2>(terminusMap.second) == tlpdr->validity))
564 {
565 // TL PDR already present with same validity don't
566 // add the PDR to the repo just return
567 return;
568 }
569 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530570 tlPDRInfo.insert_or_assign(
571 tlpdr->terminus_handle,
572 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500573 }
574 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
575 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530576 pdrTerminusHandle =
577 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800578 updateContainerId<pldm_state_sensor_pdr>(entityTree, pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500579 stateSensorPDRs.emplace_back(pdr);
580 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530581 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
582 {
583 pdrTerminusHandle =
584 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800585 updateContainerId<pldm_pdr_fru_record_set>(entityTree, pdr);
George Liu682ee182020-12-25 15:24:33 +0800586 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530587 }
588 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
589 {
590 pdrTerminusHandle =
591 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800592 updateContainerId<pldm_state_effecter_pdr>(entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530593 }
594 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
595 {
596 pdrTerminusHandle =
597 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
598 pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800599 updateContainerId<pldm_numeric_effecter_value_pdr>(
600 entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530601 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600602 // if the TLPDR is invalid update the repo accordingly
603 if (!tlValid)
604 {
605 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
606 tlValid);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500607
608 if (!isHostUp())
609 {
610 // The terminus PDR becomes invalid when the terminus
611 // itself is down. We don't need to do PDR exchange in
612 // that case, so setting the next record handle to 0.
613 nextRecordHandle = 0;
614 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600615 }
616 else
617 {
Andrew Jeffery5a945bd2024-08-01 13:15:36 +0000618 rc = pldm_pdr_add(repo, pdr.data(), respCount, true,
619 pdrTerminusHandle, &rh);
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930620 if (rc)
621 {
622 // pldm_pdr_add() assert()ed on failure to add a PDR.
623 throw std::runtime_error("Failed to add PDR");
624 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600625 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500626 }
627 }
628 }
629 if (!nextRecordHandle)
630 {
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500631 updateEntityAssociation(entityAssociations, entityTree, objPathMap,
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500632 entityMaps, oemPlatformHandler);
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -0500633 if (oemUtilsHandler)
634 {
635 oemUtilsHandler->setCoreCount(entityAssociations, entityMaps);
636 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500637 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530638 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800639 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600640 if (isHostUp())
641 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530642 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600643 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500644 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800645 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800646 entityAssociations.clear();
647
Sampa Misrac0c79482021-06-02 08:01:54 -0500648 if (merged)
649 {
650 merged = false;
651 deferredPDRRepoChgEvent =
652 std::make_unique<sdeventplus::source::Defer>(
653 event,
654 std::bind(
655 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
656 this, std::placeholders::_1));
657 }
658 }
659 else
660 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500661 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
662 {
663 isHostPdrModified = false;
664 }
665 else
666 {
667 deferredFetchPDREvent =
668 std::make_unique<sdeventplus::source::Defer>(
669 event,
670 std::bind(
671 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
672 this, nextRecordHandle, std::placeholders::_1));
673 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500674 }
675}
676
677void HostPDRHandler::_processPDRRepoChgEvent(
678 sdeventplus::source::EventBase& /*source */)
679{
680 deferredPDRRepoChgEvent.reset();
681 this->sendPDRRepositoryChgEvent(
Andrew Jefferyc14fb4b2024-07-25 22:13:09 +0930682 std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION),
Sampa Misrac0c79482021-06-02 08:01:54 -0500683 FORMAT_IS_PDR_HANDLES);
684}
685
686void HostPDRHandler::_processFetchPDREvent(
687 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
688{
689 deferredFetchPDREvent.reset();
690 if (!this->pdrRecordHandles.empty())
691 {
692 nextRecordHandle = this->pdrRecordHandles.front();
693 this->pdrRecordHandles.pop_front();
694 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500695 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
696 {
697 nextRecordHandle = this->modifiedPDRRecordHandles.front();
698 this->modifiedPDRRecordHandles.pop_front();
699 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500700 this->getHostPDR(nextRecordHandle);
701}
702
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500703void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530704{
sampmisr6decfc12021-03-02 11:07:36 +0530705 responseReceived = false;
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930706 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400707 std::vector<uint8_t> requestMsg(
708 sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500709 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
710 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
711 PLDM_BASE, request);
712 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530713 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500714 error("Failed to encode GetPLDMVersion, response code {RC}", "RC",
Riya Dixit49cfb132023-03-02 04:26:53 -0600715 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930716 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530717 return;
718 }
719
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500720 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
721 const pldm_msg* response,
722 size_t respMsgLen) {
723 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530724 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600725 error(
726 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530727 return;
728 }
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500729 info("Getting the response code '{RC}'", "RC", lg2::hex,
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500730 response->payload[0]);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500731 this->responseReceived = true;
sampmisr6decfc12021-03-02 11:07:36 +0530732 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500733 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
734 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
735 std::move(getPLDMVersionHandler));
736 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530737 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500738 error(
739 "Failed to discover remote terminus state. Assuming remote terminus as off");
sampmisr6decfc12021-03-02 11:07:36 +0530740 }
741}
742
743bool HostPDRHandler::isHostUp()
744{
745 return responseReceived;
746}
747
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530748void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600749{
750 for (const auto& stateSensorPDR : stateSensorPDRs)
751 {
752 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
753 stateSensorPDR.data());
754
755 if (!pdr)
756 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500757 error("Failed to get state sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600758 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530759 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600760 return;
761 }
762
763 uint16_t sensorId = pdr->sensor_id;
764
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530765 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600766 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530767 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600768 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530769 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600770 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530771 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600772 }
773
774 bitfield8_t sensorRearm;
775 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530776 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600777
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930778 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600779 std::vector<uint8_t> requestMsg(
780 sizeof(pldm_msg_hdr) +
781 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
782 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
783 auto rc = encode_get_state_sensor_readings_req(
784 instanceId, sensorId, sensorRearm, 0, request);
785
786 if (rc != PLDM_SUCCESS)
787 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930788 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600789 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500790 "Failed to encode get state sensor readings request for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
791 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
792 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600793 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530794 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600795 return;
796 }
797
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400798 auto getStateSensorReadingRespHandler = [=, this](
799 mctp_eid_t /*eid*/,
800 const pldm_msg*
801 response,
802 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600803 if (response == nullptr || !respMsgLen)
804 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600805 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500806 "Failed to receive response for get state sensor reading command for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}'",
807 "SENSOR_ID", sensorId, "INSTANCE", instanceId);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600808 return;
809 }
810 std::array<get_sensor_state_field, 8> stateField{};
811 uint8_t completionCode = 0;
812 uint8_t comp_sensor_count = 0;
813
814 auto rc = decode_get_state_sensor_readings_resp(
815 response, respMsgLen, &completionCode,
816 &comp_sensor_count, stateField.data());
817
818 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
819 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600820 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500821 "Failed to decode get state sensor readings response for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code'{RC}' and completion code '{CC}'",
822 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
823 rc, "CC", completionCode);
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530824 pldm::utils::reportError(
825 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600826 }
827
828 uint8_t eventState;
829 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600830
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500831 for (uint8_t sensorOffset = 0;
832 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600833 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500834 eventState = stateField[sensorOffset].present_state;
835 previousEventState =
836 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600837
838 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
839 eventState,
840 previousEventState);
841
842 SensorEntry sensorEntry{tid, sensorId};
843
844 pldm::pdr::EntityInfo entityInfo{};
845 pldm::pdr::CompositeSensorStates
846 compositeSensorStates{};
Sagar Srinivase3607a32024-02-16 03:50:53 -0600847 std::vector<pldm::pdr::StateSetId> stateSetIds{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600848
849 try
850 {
Sagar Srinivase3607a32024-02-16 03:50:53 -0600851 std::tie(entityInfo, compositeSensorStates,
852 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600853 lookupSensorInfo(sensorEntry);
854 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500855 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600856 {
857 try
858 {
859 sensorEntry.terminusID = PLDM_TID_RESERVED;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600860 std::tie(entityInfo, compositeSensorStates,
861 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600862 lookupSensorInfo(sensorEntry);
863 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500864 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600865 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600866 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600867 }
868 }
869
Manojkiran Eda07a07e22024-04-24 19:15:10 +0530870 if ((compositeSensorStates.size() > 1) &&
871 (sensorOffset > (compositeSensorStates.size() - 1)))
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600872 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500873 error(
874 "Error Invalid data, Invalid sensor offset '{SENSOR_OFFSET}'",
875 "SENSOR_OFFSET", sensorOffset);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600876 return;
877 }
878
879 const auto& possibleStates =
880 compositeSensorStates[sensorOffset];
881 if (possibleStates.find(eventState) ==
882 possibleStates.end())
883 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500884 error(
885 "Error invalid_data, Invalid event state '{STATE}'",
886 "STATE", eventState);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600887 return;
888 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400889 const auto& [containerId, entityType, entityInstance] =
890 entityInfo;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600891 auto stateSetId = stateSetIds[sensorOffset];
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600892 pldm::responder::events::StateSensorEntry
Manojkiran Edafa084702024-05-27 10:20:30 +0530893 stateSensorEntry{containerId, entityType,
Sagar Srinivase3607a32024-02-16 03:50:53 -0600894 entityInstance, sensorOffset,
Manojkiran Edafa084702024-05-27 10:20:30 +0530895 stateSetId, false};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600896 handleStateSensorEvent(stateSensorEntry, eventState);
897 }
898 };
899
900 rc = handler->registerRequest(
901 mctp_eid, instanceId, PLDM_PLATFORM,
902 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg),
903 std::move(getStateSensorReadingRespHandler));
904
905 if (rc != PLDM_SUCCESS)
906 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600907 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500908 "Failed to send request to get state sensor reading on remote terminus for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
909 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
910 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600911 }
912 }
913 }
914 }
915}
George Liu682ee182020-12-25 15:24:33 +0800916
917void HostPDRHandler::getFRURecordTableMetadataByRemote(
918 const PDRList& fruRecordSetPDRs)
919{
920 auto instanceId = instanceIdDb.next(mctp_eid);
921 std::vector<uint8_t> requestMsg(
922 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
923
924 // GetFruRecordTableMetadata
925 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
926 auto rc = encode_get_fru_record_table_metadata_req(
927 instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
928 if (rc != PLDM_SUCCESS)
929 {
930 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500931 error(
932 "Failed to encode get fru record table metadata request, response code '{RC}'",
George Liu682ee182020-12-25 15:24:33 +0800933 "RC", lg2::hex, rc);
934 return;
935 }
936
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400937 auto getFruRecordTableMetadataResponseHandler = [this, fruRecordSetPDRs](
938 mctp_eid_t /*eid*/,
939 const pldm_msg*
940 response,
941 size_t respMsgLen) {
George Liu682ee182020-12-25 15:24:33 +0800942 if (response == nullptr || !respMsgLen)
943 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500944 error(
945 "Failed to receive response for the get fru record table metadata");
George Liu682ee182020-12-25 15:24:33 +0800946 return;
947 }
948
949 uint8_t cc = 0;
950 uint8_t fru_data_major_version, fru_data_minor_version;
951 uint32_t fru_table_maximum_size, fru_table_length;
952 uint16_t total_record_set_identifiers;
953 uint16_t total;
954 uint32_t checksum;
955
956 auto rc = decode_get_fru_record_table_metadata_resp(
957 response, respMsgLen, &cc, &fru_data_major_version,
958 &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
959 &total_record_set_identifiers, &total, &checksum);
960
961 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
962 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500963 error(
964 "Failed to decode get fru record table metadata response, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +0800965 "RC", lg2::hex, rc, "CC", cc);
966 return;
967 }
968
969 // pass total to getFRURecordTableByRemote
970 this->getFRURecordTableByRemote(fruRecordSetPDRs, total);
971 };
972
973 rc = handler->registerRequest(
974 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA,
975 std::move(requestMsg),
976 std::move(getFruRecordTableMetadataResponseHandler));
977 if (rc != PLDM_SUCCESS)
978 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500979 error(
980 "Failed to send the the set state effecter states request, response code '{RC}'",
981 "RC", rc);
George Liu682ee182020-12-25 15:24:33 +0800982 }
983
984 return;
985}
986
987void HostPDRHandler::getFRURecordTableByRemote(const PDRList& fruRecordSetPDRs,
988 uint16_t totalTableRecords)
989{
990 fruRecordData.clear();
991
992 if (!totalTableRecords)
993 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500994 error("Failed to get fru record table");
George Liu682ee182020-12-25 15:24:33 +0800995 return;
996 }
997
998 auto instanceId = instanceIdDb.next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400999 std::vector<uint8_t> requestMsg(
1000 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
George Liu682ee182020-12-25 15:24:33 +08001001
1002 // send the getFruRecordTable command
1003 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
1004 auto rc = encode_get_fru_record_table_req(
1005 instanceId, 0, PLDM_GET_FIRSTPART, request,
1006 requestMsg.size() - sizeof(pldm_msg_hdr));
1007 if (rc != PLDM_SUCCESS)
1008 {
1009 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001010 error(
1011 "Failed to encode get fru record table request, response code '{RC}'",
1012 "RC", lg2::hex, rc);
George Liu682ee182020-12-25 15:24:33 +08001013 return;
1014 }
1015
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001016 auto getFruRecordTableResponseHandler = [totalTableRecords, this,
1017 fruRecordSetPDRs](
1018 mctp_eid_t /*eid*/,
1019 const pldm_msg* response,
1020 size_t respMsgLen) {
George Liu682ee182020-12-25 15:24:33 +08001021 if (response == nullptr || !respMsgLen)
1022 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001023 error("Failed to receive response for the get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001024 return;
1025 }
1026
1027 uint8_t cc = 0;
1028 uint32_t next_data_transfer_handle = 0;
1029 uint8_t transfer_flag = 0;
1030 size_t fru_record_table_length = 0;
Patrick Williams16c2a0a2024-08-16 15:20:59 -04001031 std::vector<uint8_t> fru_record_table_data(
1032 respMsgLen - sizeof(pldm_msg_hdr));
George Liu682ee182020-12-25 15:24:33 +08001033 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
1034 auto rc = decode_get_fru_record_table_resp(
Manojkiran Eda33a9cd02024-01-22 11:06:59 +05301035 responsePtr, respMsgLen, &cc, &next_data_transfer_handle,
1036 &transfer_flag, fru_record_table_data.data(),
1037 &fru_record_table_length);
George Liu682ee182020-12-25 15:24:33 +08001038
1039 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
1040 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001041 error(
1042 "Failed to decode get fru record table resp, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +08001043 "RC", lg2::hex, rc, "CC", cc);
1044 return;
1045 }
1046
1047 fruRecordData = responder::pdr_utils::parseFruRecordTable(
1048 fru_record_table_data.data(), fru_record_table_length);
1049
1050 if (totalTableRecords != fruRecordData.size())
1051 {
1052 fruRecordData.clear();
1053
Manojkiran Eda2576aec2024-06-17 12:05:17 +05301054 error("Failed to parse fru record data format.");
George Liu682ee182020-12-25 15:24:33 +08001055 return;
1056 }
1057
1058 this->setFRUDataOnDBus(fruRecordSetPDRs, fruRecordData);
1059 };
1060
1061 rc = handler->registerRequest(
1062 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE,
1063 std::move(requestMsg), std::move(getFruRecordTableResponseHandler));
1064 if (rc != PLDM_SUCCESS)
1065 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001066 error("Failed to send the the set state effecter states request");
George Liu682ee182020-12-25 15:24:33 +08001067 }
1068}
1069
1070std::optional<uint16_t> HostPDRHandler::getRSI(const PDRList& fruRecordSetPDRs,
1071 const pldm_entity& entity)
1072{
1073 for (const auto& pdr : fruRecordSetPDRs)
1074 {
1075 auto fruPdr = reinterpret_cast<const pldm_pdr_fru_record_set*>(
1076 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
1077
1078 if (fruPdr->entity_type == entity.entity_type &&
Sagar Srinivasebf8bb52023-10-06 01:15:55 -05001079 fruPdr->entity_instance == entity.entity_instance_num &&
1080 fruPdr->container_id == entity.entity_container_id)
George Liu682ee182020-12-25 15:24:33 +08001081 {
1082 return fruPdr->fru_rsi;
1083 }
1084 }
1085
1086 return std::nullopt;
1087}
1088
1089void HostPDRHandler::setFRUDataOnDBus(
Patrick Williamsd310f822023-10-07 19:01:19 -05001090 [[maybe_unused]] const PDRList& fruRecordSetPDRs,
1091 [[maybe_unused]] const std::vector<
1092 responder::pdr_utils::FruRecordDataFormat>& fruRecordData)
George Liu682ee182020-12-25 15:24:33 +08001093{
Patrick Williamsd310f822023-10-07 19:01:19 -05001094#ifdef OEM_IBM
George Liu682ee182020-12-25 15:24:33 +08001095 for (const auto& entity : objPathMap)
1096 {
1097 pldm_entity node = pldm_entity_extract(entity.second);
1098 auto fruRSI = getRSI(fruRecordSetPDRs, node);
1099
1100 for (const auto& data : fruRecordData)
1101 {
1102 if (!fruRSI || *fruRSI != data.fruRSI)
1103 {
1104 continue;
1105 }
1106
1107 if (data.fruRecType == PLDM_FRU_RECORD_TYPE_OEM)
1108 {
1109 for (const auto& tlv : data.fruTLV)
1110 {
1111 if (tlv.fruFieldType ==
1112 PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE)
1113 {
1114 CustomDBus::getCustomDBus().setLocationCode(
1115 entity.first,
1116 std::string(reinterpret_cast<const char*>(
1117 tlv.fruFieldValue.data()),
1118 tlv.fruFieldLen));
1119 }
1120 }
1121 }
1122 }
1123 }
Patrick Williamsd310f822023-10-07 19:01:19 -05001124#endif
George Liu682ee182020-12-25 15:24:33 +08001125}
1126void HostPDRHandler::createDbusObjects(const PDRList& fruRecordSetPDRs)
1127{
1128 // TODO: Creating and Refreshing dbus hosted by remote PLDM entity Fru PDRs
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001129 for (const auto& entity : objPathMap)
1130 {
1131 pldm_entity node = pldm_entity_extract(entity.second);
1132 switch (node.entity_type)
1133 {
1134 case PLDM_ENTITY_PROC | 0x8000:
1135 CustomDBus::getCustomDBus().implementCpuCoreInterface(
1136 entity.first);
1137 break;
Archana Kakanibf1fd272024-06-05 13:25:53 -05001138 case PLDM_ENTITY_SLOT:
1139 CustomDBus::getCustomDBus().implementPCIeSlotInterface(
1140 entity.first);
1141 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001142 case PLDM_ENTITY_CARD:
1143 CustomDBus::getCustomDBus().implementPCIeDeviceInterface(
1144 entity.first);
1145 break;
Kamalkumar Patel2ed986c2024-05-08 02:20:47 -05001146 case PLDM_ENTITY_SYS_BOARD:
1147 CustomDBus::getCustomDBus().implementMotherboardInterface(
1148 entity.first);
1149 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001150 default:
1151 break;
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001152 }
1153 }
George Liu682ee182020-12-25 15:24:33 +08001154 getFRURecordTableMetadataByRemote(fruRecordSetPDRs);
1155}
1156
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001157} // namespace pldm