blob: 7b5e0573b65b160d5ac4e8eb6a9deee64a94d121 [file] [log] [blame]
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001#include "host_pdr_handler.hpp"
2
George Liu682ee182020-12-25 15:24:33 +08003#include "libpldm/fru.h"
4#ifdef OEM_IBM
5#include "libpldm/fru_oem_ibm.h"
George Liu682ee182020-12-25 15:24:33 +08006
Sagar Srinivas3687e2b2023-04-10 05:08:28 -05007#include "oem/ibm/libpldmresponder/utils.hpp"
8#endif
George Liu682ee182020-12-25 15:24:33 +08009#include "custom_dbus.hpp"
10
Pavithra Barithayae8beb892020-04-14 23:24:25 -050011#include <assert.h>
12
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050013#include <nlohmann/json.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060014#include <phosphor-logging/lg2.hpp>
sampmisr6decfc12021-03-02 11:07:36 +053015#include <sdeventplus/clock.hpp>
16#include <sdeventplus/exception.hpp>
17#include <sdeventplus/source/io.hpp>
18#include <sdeventplus/source/time.hpp>
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050019
George Liu6492f522020-06-16 10:34:05 +080020#include <fstream>
George Liu96af8cb2021-07-31 15:23:45 +080021#include <type_traits>
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050022
Riya Dixit49cfb132023-03-02 04:26:53 -060023PHOSPHOR_LOG2_USING;
24
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050025namespace pldm
26{
Brad Bishop5079ac42021-08-19 18:35:06 -040027using namespace pldm::responder::events;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -050028using namespace pldm::utils;
29using namespace sdbusplus::bus::match::rules;
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050030using namespace pldm::responder::pdr_utils;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050031using Json = nlohmann::json;
32namespace fs = std::filesystem;
George Liu682ee182020-12-25 15:24:33 +080033using namespace pldm::dbus;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050034constexpr auto fruJson = "host_frus.json";
35const Json emptyJson{};
36const std::vector<Json> emptyJsonList{};
37
Manojkiran Eda3ca40452021-10-04 22:51:37 +053038template <typename T>
39uint16_t extractTerminusHandle(std::vector<uint8_t>& pdr)
40{
41 T* var = nullptr;
42 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
43 {
44 var = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
45 }
46 else
47 {
48 var = (T*)(pdr.data());
49 }
50 if (var != nullptr)
51 {
52 return var->terminus_handle;
53 }
54 return TERMINUS_HANDLE;
55}
56
George Liu96af8cb2021-07-31 15:23:45 +080057template <typename T>
58void updateContainerId(pldm_entity_association_tree* entityTree,
59 std::vector<uint8_t>& pdr)
60{
61 T* t = nullptr;
62 if (entityTree == nullptr)
63 {
64 return;
65 }
66 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
67 {
68 t = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
69 }
70 else
71 {
72 t = (T*)(pdr.data());
73 }
74 if (t == nullptr)
75 {
76 return;
77 }
78
79 pldm_entity entity{t->entity_type, t->entity_instance, t->container_id};
80 auto node = pldm_entity_association_tree_find_with_locality(entityTree,
81 &entity, true);
82 if (node)
83 {
84 pldm_entity e = pldm_entity_extract(node);
85 t->container_id = e.entity_container_id;
86 }
87}
88
Tom Joseph74f27c72021-05-16 07:58:53 -070089HostPDRHandler::HostPDRHandler(
90 int mctp_fd, uint8_t mctp_eid, sdeventplus::Event& event, pldm_pdr* repo,
91 const std::string& eventsJsonsDir, pldm_entity_association_tree* entityTree,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093092 pldm_entity_association_tree* bmcEntityTree,
93 pldm::InstanceIdDb& instanceIdDb,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050094 pldm::requester::Handler<pldm::requester::Request>* handler,
95 pldm::responder::oem_platform::Handler* oemPlatformHandler) :
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050096 mctp_fd(mctp_fd),
Pavithra Barithaya3aec9972020-12-14 01:55:44 -060097 mctp_eid(mctp_eid), event(event), repo(repo),
98 stateSensorHandler(eventsJsonsDir), entityTree(entityTree),
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050099 bmcEntityTree(bmcEntityTree), instanceIdDb(instanceIdDb), handler(handler),
100 oemPlatformHandler(oemPlatformHandler)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500101{
George Liuacf2c8c2021-05-10 14:08:52 +0800102 mergedHostParents = false;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500103 fs::path hostFruJson(fs::path(HOST_JSONS_DIR) / fruJson);
104 if (fs::exists(hostFruJson))
105 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500106 // Note parent entities for entities sent down by the host firmware.
107 // This will enable a merge of entity associations.
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500108 try
109 {
110 std::ifstream jsonFile(hostFruJson);
111 auto data = Json::parse(jsonFile, nullptr, false);
112 if (data.is_discarded())
113 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600114 error("Parsing Host FRU json file failed");
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500115 }
116 else
117 {
118 auto entities = data.value("entities", emptyJsonList);
119 for (auto& entity : entities)
120 {
121 EntityType entityType = entity.value("entity_type", 0);
122 auto parent = entity.value("parent", emptyJson);
123 pldm_entity p{};
124 p.entity_type = parent.value("entity_type", 0);
125 p.entity_instance_num = parent.value("entity_instance", 0);
126 parents.emplace(entityType, std::move(p));
127 }
128 }
129 }
130 catch (const std::exception& e)
131 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600132 error("Parsing Host FRU json file failed, exception = {ERR_EXCEP}",
133 "ERR_EXCEP", e.what());
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500134 }
135 }
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500136
Patrick Williams84b790c2022-07-22 19:26:56 -0500137 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500138 pldm::utils::DBusHandler::getBus(),
139 propertiesChanged("/xyz/openbmc_project/state/host0",
140 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -0500141 [this, repo, entityTree, bmcEntityTree](sdbusplus::message_t& msg) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500142 DbusChangedProps props{};
143 std::string intf;
144 msg.read(intf, props);
145 const auto itr = props.find("CurrentHostState");
146 if (itr != props.end())
147 {
148 PropertyValue value = itr->second;
149 auto propVal = std::get<std::string>(value);
150 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500151 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500152 // Delete all the remote terminus information
153 std::erase_if(tlPDRInfo, [](const auto& item) {
154 auto const& [key, value] = item;
155 return key != TERMINUS_HANDLE;
156 });
157 pldm_pdr_remove_remote_pdrs(repo);
158 pldm_entity_association_tree_destroy_root(entityTree);
159 pldm_entity_association_tree_copy_root(bmcEntityTree,
160 entityTree);
161 this->sensorMap.clear();
162 this->responseReceived = false;
George Liuacf2c8c2021-05-10 14:08:52 +0800163 this->mergedHostParents = false;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500164 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500165 }
Patrick Williamsa6756622023-10-20 11:19:15 -0500166 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500167}
168
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500169void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500170{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500171 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500172 modifiedPDRRecordHandles.clear();
173
174 if (isHostPdrModified)
175 {
176 modifiedPDRRecordHandles = std::move(recordHandles);
177 }
178 else
179 {
180 pdrRecordHandles = std::move(recordHandles);
181 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500182
183 // Defer the actual fetch of PDRs from the host (by queuing the call on the
184 // main event loop). That way, we can respond to the platform event msg from
185 // the host firmware.
186 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
187 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
188 std::placeholders::_1));
189}
190
191void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
192{
Sampa Misrac0c79482021-06-02 08:01:54 -0500193 getHostPDR();
194}
195
196void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
197{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500198 pdrFetchEvent.reset();
199
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500200 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
201 PLDM_GET_PDR_REQ_BYTES);
202 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500203 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500204 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
205 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500206 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500207 recordHandle = modifiedPDRRecordHandles.front();
208 modifiedPDRRecordHandles.pop_front();
209 }
210 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
211 {
212 recordHandle = pdrRecordHandles.front();
213 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500214 }
215 else
216 {
217 recordHandle = nextRecordHandle;
218 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930219 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500220
Patrick Williams6da4f912023-05-10 07:50:53 -0500221 auto rc = encode_get_pdr_req(instanceId, recordHandle, 0,
222 PLDM_GET_FIRSTPART, UINT16_MAX, 0, request,
223 PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500224 if (rc != PLDM_SUCCESS)
225 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930226 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600227 error("Failed to encode_get_pdr_req, rc = {RC}", "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500228 return;
229 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500230
Sampa Misrac0c79482021-06-02 08:01:54 -0500231 rc = handler->registerRequest(
232 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
233 std::move(requestMsg),
234 std::move(std::bind_front(&HostPDRHandler::processHostPDRs, this)));
235 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500236 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600237 error("Failed to send the GetPDR request to Host");
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500238 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500239}
240
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600241int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
242 pdr::EventState state)
243{
244 auto rc = stateSensorHandler.eventAction(entry, state);
245 if (rc != PLDM_SUCCESS)
246 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600247 error("Failed to fetch and update D-bus property, rc = {RC}", "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600248 return rc;
249 }
250 return PLDM_SUCCESS;
251}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500252
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500253void HostPDRHandler::mergeEntityAssociations(
254 const std::vector<uint8_t>& pdr, [[maybe_unused]] const uint32_t& size,
255 [[maybe_unused]] const uint32_t& record_handle)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500256{
257 size_t numEntities{};
258 pldm_entity* entities = nullptr;
259 bool merged = false;
260 auto entityPdr = reinterpret_cast<pldm_pdr_entity_association*>(
261 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
262
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500263 if (oemPlatformHandler &&
264 oemPlatformHandler->checkRecordHandleInRange(record_handle))
265 {
266 // Adding the remote range PDRs to the repo before merging it
267 uint32_t handle = record_handle;
268 pldm_pdr_add_check(repo, pdr.data(), size, true, 0xFFFF, &handle);
269 }
270
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500271 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
272 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800273 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500274 {
George Liuacf2c8c2021-05-10 14:08:52 +0800275 pldm_entity_node* pNode = nullptr;
276 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500277 {
George Liuacf2c8c2021-05-10 14:08:52 +0800278 pNode = pldm_entity_association_tree_find_with_locality(
279 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500280 }
George Liuacf2c8c2021-05-10 14:08:52 +0800281 else
282 {
283 pNode = pldm_entity_association_tree_find_with_locality(
284 entityTree, &entities[0], true);
285 }
286 if (!pNode)
287 {
288 return;
289 }
290
George Liudf9a6d32020-12-22 16:27:16 +0800291 Entities entityAssoc;
292 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800293 for (size_t i = 1; i < numEntities; ++i)
294 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500295 bool isUpdateContainerId = true;
296 if (oemPlatformHandler)
297 {
298 isUpdateContainerId =
299 pldm::responder::utils::checkIfLogicalBitSet(
300 entities[i].entity_container_id);
301 }
George Liudf9a6d32020-12-22 16:27:16 +0800302 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800303 entityTree, &entities[i], entities[i].entity_instance_num,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500304 pNode, entityPdr->association_type, true, isUpdateContainerId,
305 0xFFFF);
306 if (!node)
307 {
308 continue;
309 }
George Liuacf2c8c2021-05-10 14:08:52 +0800310 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800311 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800312 }
313
314 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800315 if (merged)
316 {
317 entityAssociations.push_back(entityAssoc);
318 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500319 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500320
321 if (merged)
322 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500323 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500324 pldm_entity_node* node = nullptr;
325 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
326 if (node == nullptr)
327 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600328 error("could not find referrence of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500329 }
330 else
331 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500332 int rc = 0;
333 if (oemPlatformHandler)
334 {
335 auto record = oemPlatformHandler->fetchLastBMCRecord(repo);
336
337 uint32_t record_handle = pldm_pdr_get_record_handle(repo,
338 record);
339
340 rc =
341 pldm_entity_association_pdr_add_from_node_with_record_handle(
342 node, repo, &entities, numEntities, true,
343 TERMINUS_HANDLE, (record_handle + 1));
344 }
345 else
346 {
347 rc = pldm_entity_association_pdr_add_from_node_check(
348 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
349 }
350
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930351 if (rc)
352 {
353 error(
354 "Failed to add entity association PDR from node: {LIBPLDM_ERROR}",
355 "LIBPLDM_ERROR", rc);
356 }
Sampa Misra719ed392021-06-04 05:15:13 -0500357 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500358 }
Sampa Misra719ed392021-06-04 05:15:13 -0500359 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500360}
361
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500362void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
363 uint8_t eventDataFormat)
364{
365 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
366
367 // Extract from the PDR repo record handles of PDRs we want the host
368 // to pull up.
369 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
370 std::vector<uint8_t> numsOfChangeEntries(1);
371 std::vector<std::vector<ChangeEntry>> changeEntries(
372 numsOfChangeEntries.size());
373 for (auto pdrType : pdrTypes)
374 {
375 const pldm_pdr_record* record{};
376 do
377 {
378 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
379 nullptr, nullptr);
380 if (record && pldm_pdr_record_is_remote(record))
381 {
382 changeEntries[0].push_back(
383 pldm_pdr_get_record_handle(repo, record));
384 }
385 } while (record);
386 }
387 if (changeEntries.empty())
388 {
389 return;
390 }
391 numsOfChangeEntries[0] = changeEntries[0].size();
392
393 // Encode PLDM platform event msg to indicate a PDR repo change.
394 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
395 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
396 changeEntries[0].size() * sizeof(uint32_t);
397 std::vector<uint8_t> eventDataVec{};
398 eventDataVec.resize(maxSize);
399 auto eventData =
400 reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
401 eventDataVec.data());
402 size_t actualSize{};
403 auto firstEntry = changeEntries[0].data();
404 auto rc = encode_pldm_pdr_repository_chg_event_data(
405 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
406 &firstEntry, eventData, &actualSize, maxSize);
407 if (rc != PLDM_SUCCESS)
408 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600409 error("Failed to encode_pldm_pdr_repository_chg_event_data, rc = {RC}",
410 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500411 return;
412 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930413 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500414 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
415 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
416 actualSize);
417 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
418 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600419 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
420 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500421 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500422 if (rc != PLDM_SUCCESS)
423 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930424 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600425 error("Failed to encode_platform_event_message_req, rc = {RC}", "RC",
426 rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500427 return;
428 }
429
Patrick Williams6da4f912023-05-10 07:50:53 -0500430 auto platformEventMessageResponseHandler =
431 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700432 if (response == nullptr || !respMsgLen)
433 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600434 error(
435 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700436 return;
437 }
438
439 uint8_t completionCode{};
440 uint8_t status{};
441 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500442 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
443 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500444 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700445 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600446 error(
447 "Failed to decode_platform_event_message_resp: {RC}, cc = {CC}",
448 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Tom Joseph74f27c72021-05-16 07:58:53 -0700449 }
450 };
451
Sampa Misrac0c79482021-06-02 08:01:54 -0500452 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500453 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700454 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500455 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500456 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600457 error("Failed to send the PDR repository changed event request");
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500458 }
459}
460
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530461void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500462{
463 for (const auto& pdr : stateSensorPDRs)
464 {
465 SensorEntry sensorEntry{};
466 const auto& [terminusHandle, sensorID, sensorInfo] =
467 responder::pdr_utils::parseStateSensorPDR(pdr);
468 sensorEntry.sensorID = sensorID;
469 try
470 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530471 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500472 }
473 // If there is no mapping for terminusHandle assign the reserved TID
474 // value of 0xFF to indicate that.
475 catch (const std::out_of_range& e)
476 {
477 sensorEntry.terminusID = PLDM_TID_RESERVED;
478 }
479 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
480 }
481}
482
Sampa Misrac0c79482021-06-02 08:01:54 -0500483void HostPDRHandler::processHostPDRs(mctp_eid_t /*eid*/,
484 const pldm_msg* response,
485 size_t respMsgLen)
486{
487 static bool merged = false;
488 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800489 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500490 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600491 uint8_t tlEid = 0;
492 bool tlValid = true;
493 uint32_t rh = 0;
494 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530495 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600496 uint8_t tid = 0;
497
Sampa Misrac0c79482021-06-02 08:01:54 -0500498 uint8_t completionCode{};
499 uint32_t nextDataTransferHandle{};
500 uint8_t transferFlag{};
501 uint16_t respCount{};
502 uint8_t transferCRC{};
503 if (response == nullptr || !respMsgLen)
504 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600505 error("Failed to receive response for the GetPDR command");
Sampa Misrac0c79482021-06-02 08:01:54 -0500506 return;
507 }
508
509 auto rc = decode_get_pdr_resp(
510 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
511 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
512 nullptr, 0, &transferCRC);
513 std::vector<uint8_t> responsePDRMsg;
514 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
515 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500516 if (rc != PLDM_SUCCESS)
517 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600518 error("Failed to decode_get_pdr_resp, rc = {RC}", "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500519 return;
520 }
521 else
522 {
523 std::vector<uint8_t> pdr(respCount, 0);
524 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
525 &nextRecordHandle, &nextDataTransferHandle,
526 &transferFlag, &respCount, pdr.data(),
527 respCount, &transferCRC);
528 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
529 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600530 error("Failed to decode_get_pdr_resp: rc = {RC}, cc = {CC}", "RC",
531 rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -0500532 return;
533 }
534 else
535 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600536 // when nextRecordHandle is 0, we need the recordHandle of the last
537 // PDR and not 0-1.
538 if (!nextRecordHandle)
539 {
540 rh = nextRecordHandle;
541 }
542 else
543 {
544 rh = nextRecordHandle - 1;
545 }
546
Sampa Misrac0c79482021-06-02 08:01:54 -0500547 auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600548 if (!rh)
549 {
550 rh = pdrHdr->record_handle;
551 }
552
Sampa Misrac0c79482021-06-02 08:01:54 -0500553 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
554 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500555 this->mergeEntityAssociations(pdr, respCount, rh);
Sampa Misrac0c79482021-06-02 08:01:54 -0500556 merged = true;
557 }
558 else
559 {
560 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
561 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530562 pdrTerminusHandle =
563 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500564 auto tlpdr =
565 reinterpret_cast<const pldm_terminus_locator_pdr*>(
566 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600567
568 terminusHandle = tlpdr->terminus_handle;
569 tid = tlpdr->tid;
570 auto terminus_locator_type = tlpdr->terminus_locator_type;
571 if (terminus_locator_type ==
572 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
573 {
574 auto locatorValue = reinterpret_cast<
575 const pldm_terminus_locator_type_mctp_eid*>(
576 tlpdr->terminus_locator_value);
577 tlEid = static_cast<uint8_t>(locatorValue->eid);
578 }
579 if (tlpdr->validity == 0)
580 {
581 tlValid = false;
582 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500583 for (const auto& terminusMap : tlPDRInfo)
584 {
585 if ((terminusHandle == (terminusMap.first)) &&
586 (get<1>(terminusMap.second) == tlEid) &&
587 (get<2>(terminusMap.second) == tlpdr->validity))
588 {
589 // TL PDR already present with same validity don't
590 // add the PDR to the repo just return
591 return;
592 }
593 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530594 tlPDRInfo.insert_or_assign(
595 tlpdr->terminus_handle,
596 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500597 }
598 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
599 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530600 pdrTerminusHandle =
601 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800602 updateContainerId<pldm_state_sensor_pdr>(entityTree, pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500603 stateSensorPDRs.emplace_back(pdr);
604 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530605 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
606 {
607 pdrTerminusHandle =
608 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800609 updateContainerId<pldm_pdr_fru_record_set>(entityTree, pdr);
George Liu682ee182020-12-25 15:24:33 +0800610 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530611 }
612 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
613 {
614 pdrTerminusHandle =
615 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800616 updateContainerId<pldm_state_effecter_pdr>(entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530617 }
618 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
619 {
620 pdrTerminusHandle =
621 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
622 pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800623 updateContainerId<pldm_numeric_effecter_value_pdr>(
624 entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530625 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600626 // if the TLPDR is invalid update the repo accordingly
627 if (!tlValid)
628 {
629 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
630 tlValid);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500631
632 if (!isHostUp())
633 {
634 // The terminus PDR becomes invalid when the terminus
635 // itself is down. We don't need to do PDR exchange in
636 // that case, so setting the next record handle to 0.
637 nextRecordHandle = 0;
638 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600639 }
640 else
641 {
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930642 rc = pldm_pdr_add_check(repo, pdr.data(), respCount, true,
643 pdrTerminusHandle, &rh);
644 if (rc)
645 {
646 // pldm_pdr_add() assert()ed on failure to add a PDR.
647 throw std::runtime_error("Failed to add PDR");
648 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600649 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500650 }
651 }
652 }
653 if (!nextRecordHandle)
654 {
George Liudf9a6d32020-12-22 16:27:16 +0800655 updateEntityAssociation(entityAssociations, entityTree, objPathMap);
656
Sampa Misrac0c79482021-06-02 08:01:54 -0500657 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530658 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800659 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600660 if (isHostUp())
661 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530662 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600663 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500664 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800665 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800666 entityAssociations.clear();
667
Sampa Misrac0c79482021-06-02 08:01:54 -0500668 if (merged)
669 {
670 merged = false;
671 deferredPDRRepoChgEvent =
672 std::make_unique<sdeventplus::source::Defer>(
673 event,
674 std::bind(
675 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
676 this, std::placeholders::_1));
677 }
678 }
679 else
680 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500681 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
682 {
683 isHostPdrModified = false;
684 }
685 else
686 {
687 deferredFetchPDREvent =
688 std::make_unique<sdeventplus::source::Defer>(
689 event,
690 std::bind(
691 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
692 this, nextRecordHandle, std::placeholders::_1));
693 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500694 }
695}
696
697void HostPDRHandler::_processPDRRepoChgEvent(
698 sdeventplus::source::EventBase& /*source */)
699{
700 deferredPDRRepoChgEvent.reset();
701 this->sendPDRRepositoryChgEvent(
702 std::move(std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION)),
703 FORMAT_IS_PDR_HANDLES);
704}
705
706void HostPDRHandler::_processFetchPDREvent(
707 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
708{
709 deferredFetchPDREvent.reset();
710 if (!this->pdrRecordHandles.empty())
711 {
712 nextRecordHandle = this->pdrRecordHandles.front();
713 this->pdrRecordHandles.pop_front();
714 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500715 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
716 {
717 nextRecordHandle = this->modifiedPDRRecordHandles.front();
718 this->modifiedPDRRecordHandles.pop_front();
719 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500720 this->getHostPDR(nextRecordHandle);
721}
722
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500723void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530724{
sampmisr6decfc12021-03-02 11:07:36 +0530725 responseReceived = false;
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930726 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500727 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
728 PLDM_GET_VERSION_REQ_BYTES);
729 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
730 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
731 PLDM_BASE, request);
732 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530733 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600734 error("GetPLDMVersion encode failure. PLDM error code = {RC}", "RC",
735 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930736 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530737 return;
738 }
739
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500740 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
741 const pldm_msg* response,
742 size_t respMsgLen) {
743 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530744 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600745 error(
746 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530747 return;
748 }
Riya Dixit49cfb132023-03-02 04:26:53 -0600749 info("Getting the response. PLDM RC = {RC}", "RC", lg2::hex,
750 static_cast<uint16_t>(response->payload[0]));
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500751 this->responseReceived = true;
752 getHostPDR();
sampmisr6decfc12021-03-02 11:07:36 +0530753 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500754 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
755 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
756 std::move(getPLDMVersionHandler));
757 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530758 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600759 error("Failed to discover Host state. Assuming Host as off");
sampmisr6decfc12021-03-02 11:07:36 +0530760 }
761}
762
763bool HostPDRHandler::isHostUp()
764{
765 return responseReceived;
766}
767
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530768void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600769{
770 for (const auto& stateSensorPDR : stateSensorPDRs)
771 {
772 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
773 stateSensorPDR.data());
774
775 if (!pdr)
776 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600777 error("Failed to get State sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600778 pldm::utils::reportError(
779 "xyz.openbmc_project.bmc.pldm.InternalFailure");
780 return;
781 }
782
783 uint16_t sensorId = pdr->sensor_id;
784
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530785 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600786 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530787 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600788 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530789 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600790 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530791 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600792 }
793
794 bitfield8_t sensorRearm;
795 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530796 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600797
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930798 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600799 std::vector<uint8_t> requestMsg(
800 sizeof(pldm_msg_hdr) +
801 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
802 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
803 auto rc = encode_get_state_sensor_readings_req(
804 instanceId, sensorId, sensorRearm, 0, request);
805
806 if (rc != PLDM_SUCCESS)
807 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930808 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600809 error(
810 "Failed to encode_get_state_sensor_readings_req, rc = {RC}",
811 "RC", rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600812 pldm::utils::reportError(
813 "xyz.openbmc_project.bmc.pldm.InternalFailure");
814 return;
815 }
816
Patrick Williams6da4f912023-05-10 07:50:53 -0500817 auto getStateSensorReadingRespHandler =
818 [=, this](mctp_eid_t /*eid*/, const pldm_msg* response,
819 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600820 if (response == nullptr || !respMsgLen)
821 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600822 error(
823 "Failed to receive response for getStateSensorReading command");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600824 return;
825 }
826 std::array<get_sensor_state_field, 8> stateField{};
827 uint8_t completionCode = 0;
828 uint8_t comp_sensor_count = 0;
829
830 auto rc = decode_get_state_sensor_readings_resp(
831 response, respMsgLen, &completionCode,
832 &comp_sensor_count, stateField.data());
833
834 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
835 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600836 error(
837 "Failed to decode_get_state_sensor_readings_resp, rc = {RC} cc = {CC}",
838 "RC", rc, "CC",
839 static_cast<unsigned>(completionCode));
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600840 pldm::utils::reportError(
841 "xyz.openbmc_project.bmc.pldm.InternalFailure");
842 }
843
844 uint8_t eventState;
845 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600846
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500847 for (uint8_t sensorOffset = 0;
848 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600849 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500850 eventState = stateField[sensorOffset].present_state;
851 previousEventState =
852 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600853
854 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
855 eventState,
856 previousEventState);
857
858 SensorEntry sensorEntry{tid, sensorId};
859
860 pldm::pdr::EntityInfo entityInfo{};
861 pldm::pdr::CompositeSensorStates
862 compositeSensorStates{};
863
864 try
865 {
866 std::tie(entityInfo, compositeSensorStates) =
867 lookupSensorInfo(sensorEntry);
868 }
869 catch (const std::out_of_range& e)
870 {
871 try
872 {
873 sensorEntry.terminusID = PLDM_TID_RESERVED;
874 std::tie(entityInfo, compositeSensorStates) =
875 lookupSensorInfo(sensorEntry);
876 }
877 catch (const std::out_of_range& e)
878 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600879 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600880 }
881 }
882
883 if (sensorOffset > compositeSensorStates.size())
884 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600885 error("Error Invalid data, Invalid sensor offset");
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 Dixit49cfb132023-03-02 04:26:53 -0600894 error("Error invalid_data, Invalid event state");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600895 return;
896 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500897 const auto& [containerId, entityType,
898 entityInstance] = entityInfo;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600899 pldm::responder::events::StateSensorEntry
900 stateSensorEntry{containerId, entityType,
901 entityInstance, sensorOffset};
902 handleStateSensorEvent(stateSensorEntry, eventState);
903 }
904 };
905
906 rc = handler->registerRequest(
907 mctp_eid, instanceId, PLDM_PLATFORM,
908 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg),
909 std::move(getStateSensorReadingRespHandler));
910
911 if (rc != PLDM_SUCCESS)
912 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600913 error(
914 "Failed to send request to get State sensor reading on Host");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600915 }
916 }
917 }
918 }
919}
George Liu682ee182020-12-25 15:24:33 +0800920
921void HostPDRHandler::getFRURecordTableMetadataByRemote(
922 const PDRList& fruRecordSetPDRs)
923{
924 auto instanceId = instanceIdDb.next(mctp_eid);
925 std::vector<uint8_t> requestMsg(
926 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
927
928 // GetFruRecordTableMetadata
929 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
930 auto rc = encode_get_fru_record_table_metadata_req(
931 instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
932 if (rc != PLDM_SUCCESS)
933 {
934 instanceIdDb.free(mctp_eid, instanceId);
935 lg2::error(
936 "Failed to encode_get_fru_record_table_metadata_req, rc = {RC}",
937 "RC", lg2::hex, rc);
938 return;
939 }
940
941 auto getFruRecordTableMetadataResponseHandler =
942 [this, fruRecordSetPDRs](mctp_eid_t /*eid*/, const pldm_msg* response,
943 size_t respMsgLen) {
944 if (response == nullptr || !respMsgLen)
945 {
946 lg2::error(
947 "Failed to receive response for the Get FRU Record Table Metadata");
948 return;
949 }
950
951 uint8_t cc = 0;
952 uint8_t fru_data_major_version, fru_data_minor_version;
953 uint32_t fru_table_maximum_size, fru_table_length;
954 uint16_t total_record_set_identifiers;
955 uint16_t total;
956 uint32_t checksum;
957
958 auto rc = decode_get_fru_record_table_metadata_resp(
959 response, respMsgLen, &cc, &fru_data_major_version,
960 &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
961 &total_record_set_identifiers, &total, &checksum);
962
963 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
964 {
965 lg2::error(
966 "Faile to decode get fru record table metadata resp, Message Error: {RC}, cc: {CC}",
967 "RC", lg2::hex, rc, "CC", cc);
968 return;
969 }
970
971 // pass total to getFRURecordTableByRemote
972 this->getFRURecordTableByRemote(fruRecordSetPDRs, total);
973 };
974
975 rc = handler->registerRequest(
976 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA,
977 std::move(requestMsg),
978 std::move(getFruRecordTableMetadataResponseHandler));
979 if (rc != PLDM_SUCCESS)
980 {
981 lg2::error("Failed to send the the Set State Effecter States request");
982 }
983
984 return;
985}
986
987void HostPDRHandler::getFRURecordTableByRemote(const PDRList& fruRecordSetPDRs,
988 uint16_t totalTableRecords)
989{
990 fruRecordData.clear();
991
992 if (!totalTableRecords)
993 {
994 lg2::error("Failed to get fru record table");
995 return;
996 }
997
998 auto instanceId = instanceIdDb.next(mctp_eid);
999 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
1000 PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
1001
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);
1010 lg2::error("Failed to encode_get_fru_record_table_req, rc = {RC}", "RC",
1011 lg2::hex, rc);
1012 return;
1013 }
1014
1015 auto getFruRecordTableResponseHandler =
1016 [totalTableRecords, this, fruRecordSetPDRs](
1017 mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
1018 if (response == nullptr || !respMsgLen)
1019 {
1020 lg2::error(
1021 "Failed to receive response for the Get FRU Record Table");
1022 return;
1023 }
1024
1025 uint8_t cc = 0;
1026 uint32_t next_data_transfer_handle = 0;
1027 uint8_t transfer_flag = 0;
1028 size_t fru_record_table_length = 0;
1029 std::vector<uint8_t> fru_record_table_data(respMsgLen -
1030 sizeof(pldm_msg_hdr));
1031 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
1032 auto rc = decode_get_fru_record_table_resp(
1033 responsePtr, respMsgLen - sizeof(pldm_msg_hdr), &cc,
1034 &next_data_transfer_handle, &transfer_flag,
1035 fru_record_table_data.data(), &fru_record_table_length);
1036
1037 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
1038 {
1039 lg2::error(
1040 "Failed to decode get fru record table resp, Message Error: {RC}, cc: {CC}",
1041 "RC", lg2::hex, rc, "CC", cc);
1042 return;
1043 }
1044
1045 fruRecordData = responder::pdr_utils::parseFruRecordTable(
1046 fru_record_table_data.data(), fru_record_table_length);
1047
1048 if (totalTableRecords != fruRecordData.size())
1049 {
1050 fruRecordData.clear();
1051
1052 lg2::error("failed to parse fru recrod data format.");
1053 return;
1054 }
1055
1056 this->setFRUDataOnDBus(fruRecordSetPDRs, fruRecordData);
1057 };
1058
1059 rc = handler->registerRequest(
1060 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE,
1061 std::move(requestMsg), std::move(getFruRecordTableResponseHandler));
1062 if (rc != PLDM_SUCCESS)
1063 {
1064 lg2::error("Failed to send the the Set State Effecter States request");
1065 }
1066}
1067
1068std::optional<uint16_t> HostPDRHandler::getRSI(const PDRList& fruRecordSetPDRs,
1069 const pldm_entity& entity)
1070{
1071 for (const auto& pdr : fruRecordSetPDRs)
1072 {
1073 auto fruPdr = reinterpret_cast<const pldm_pdr_fru_record_set*>(
1074 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
1075
1076 if (fruPdr->entity_type == entity.entity_type &&
Sagar Srinivasebf8bb52023-10-06 01:15:55 -05001077 fruPdr->entity_instance == entity.entity_instance_num &&
1078 fruPdr->container_id == entity.entity_container_id)
George Liu682ee182020-12-25 15:24:33 +08001079 {
1080 return fruPdr->fru_rsi;
1081 }
1082 }
1083
1084 return std::nullopt;
1085}
1086
1087void HostPDRHandler::setFRUDataOnDBus(
Patrick Williamsd310f822023-10-07 19:01:19 -05001088 [[maybe_unused]] const PDRList& fruRecordSetPDRs,
1089 [[maybe_unused]] const std::vector<
1090 responder::pdr_utils::FruRecordDataFormat>& fruRecordData)
George Liu682ee182020-12-25 15:24:33 +08001091{
Patrick Williamsd310f822023-10-07 19:01:19 -05001092#ifdef OEM_IBM
George Liu682ee182020-12-25 15:24:33 +08001093 for (const auto& entity : objPathMap)
1094 {
1095 pldm_entity node = pldm_entity_extract(entity.second);
1096 auto fruRSI = getRSI(fruRecordSetPDRs, node);
1097
1098 for (const auto& data : fruRecordData)
1099 {
1100 if (!fruRSI || *fruRSI != data.fruRSI)
1101 {
1102 continue;
1103 }
1104
1105 if (data.fruRecType == PLDM_FRU_RECORD_TYPE_OEM)
1106 {
1107 for (const auto& tlv : data.fruTLV)
1108 {
1109 if (tlv.fruFieldType ==
1110 PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE)
1111 {
1112 CustomDBus::getCustomDBus().setLocationCode(
1113 entity.first,
1114 std::string(reinterpret_cast<const char*>(
1115 tlv.fruFieldValue.data()),
1116 tlv.fruFieldLen));
1117 }
1118 }
1119 }
1120 }
1121 }
Patrick Williamsd310f822023-10-07 19:01:19 -05001122#endif
George Liu682ee182020-12-25 15:24:33 +08001123}
1124void HostPDRHandler::createDbusObjects(const PDRList& fruRecordSetPDRs)
1125{
1126 // TODO: Creating and Refreshing dbus hosted by remote PLDM entity Fru PDRs
1127
1128 getFRURecordTableMetadataByRemote(fruRecordSetPDRs);
1129}
1130
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001131} // namespace pldm