blob: 0d85d2bcbfd9675da90e14a809378718cd842afa [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
George Liu682ee182020-12-25 15:24:33 +08007#include "custom_dbus.hpp"
8
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;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050029using Json = nlohmann::json;
30namespace fs = std::filesystem;
George Liu682ee182020-12-25 15:24:33 +080031using namespace pldm::dbus;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050032constexpr auto fruJson = "host_frus.json";
33const Json emptyJson{};
34const std::vector<Json> emptyJsonList{};
35
Manojkiran Eda3ca40452021-10-04 22:51:37 +053036template <typename T>
37uint16_t extractTerminusHandle(std::vector<uint8_t>& pdr)
38{
39 T* var = nullptr;
40 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
41 {
42 var = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
43 }
44 else
45 {
46 var = (T*)(pdr.data());
47 }
48 if (var != nullptr)
49 {
50 return var->terminus_handle;
51 }
52 return TERMINUS_HANDLE;
53}
54
George Liu96af8cb2021-07-31 15:23:45 +080055template <typename T>
56void updateContainerId(pldm_entity_association_tree* entityTree,
57 std::vector<uint8_t>& pdr)
58{
59 T* t = nullptr;
60 if (entityTree == nullptr)
61 {
62 return;
63 }
64 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
65 {
66 t = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
67 }
68 else
69 {
70 t = (T*)(pdr.data());
71 }
72 if (t == nullptr)
73 {
74 return;
75 }
76
77 pldm_entity entity{t->entity_type, t->entity_instance, t->container_id};
78 auto node = pldm_entity_association_tree_find_with_locality(entityTree,
79 &entity, true);
80 if (node)
81 {
82 pldm_entity e = pldm_entity_extract(node);
83 t->container_id = e.entity_container_id;
84 }
85}
86
Tom Joseph74f27c72021-05-16 07:58:53 -070087HostPDRHandler::HostPDRHandler(
88 int mctp_fd, uint8_t mctp_eid, sdeventplus::Event& event, pldm_pdr* repo,
89 const std::string& eventsJsonsDir, pldm_entity_association_tree* entityTree,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093090 pldm_entity_association_tree* bmcEntityTree,
91 pldm::InstanceIdDb& instanceIdDb,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050092 pldm::requester::Handler<pldm::requester::Request>* handler,
93 pldm::responder::oem_platform::Handler* oemPlatformHandler) :
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050094 mctp_fd(mctp_fd),
Pavithra Barithaya3aec9972020-12-14 01:55:44 -060095 mctp_eid(mctp_eid), event(event), repo(repo),
96 stateSensorHandler(eventsJsonsDir), entityTree(entityTree),
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050097 bmcEntityTree(bmcEntityTree), instanceIdDb(instanceIdDb), handler(handler),
98 oemPlatformHandler(oemPlatformHandler)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050099{
George Liuacf2c8c2021-05-10 14:08:52 +0800100 mergedHostParents = false;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500101 fs::path hostFruJson(fs::path(HOST_JSONS_DIR) / fruJson);
102 if (fs::exists(hostFruJson))
103 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500104 // Note parent entities for entities sent down by the host firmware.
105 // This will enable a merge of entity associations.
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500106 try
107 {
108 std::ifstream jsonFile(hostFruJson);
109 auto data = Json::parse(jsonFile, nullptr, false);
110 if (data.is_discarded())
111 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600112 error("Parsing Host FRU json file failed");
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500113 }
114 else
115 {
116 auto entities = data.value("entities", emptyJsonList);
117 for (auto& entity : entities)
118 {
119 EntityType entityType = entity.value("entity_type", 0);
120 auto parent = entity.value("parent", emptyJson);
121 pldm_entity p{};
122 p.entity_type = parent.value("entity_type", 0);
123 p.entity_instance_num = parent.value("entity_instance", 0);
124 parents.emplace(entityType, std::move(p));
125 }
126 }
127 }
128 catch (const std::exception& e)
129 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600130 error("Parsing Host FRU json file failed, exception = {ERR_EXCEP}",
131 "ERR_EXCEP", e.what());
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500132 }
133 }
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500134
Patrick Williams84b790c2022-07-22 19:26:56 -0500135 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500136 pldm::utils::DBusHandler::getBus(),
137 propertiesChanged("/xyz/openbmc_project/state/host0",
138 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -0500139 [this, repo, entityTree, bmcEntityTree](sdbusplus::message_t& msg) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500140 DbusChangedProps props{};
141 std::string intf;
142 msg.read(intf, props);
143 const auto itr = props.find("CurrentHostState");
144 if (itr != props.end())
145 {
146 PropertyValue value = itr->second;
147 auto propVal = std::get<std::string>(value);
148 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500149 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500150 // Delete all the remote terminus information
151 std::erase_if(tlPDRInfo, [](const auto& item) {
152 auto const& [key, value] = item;
153 return key != TERMINUS_HANDLE;
154 });
155 pldm_pdr_remove_remote_pdrs(repo);
156 pldm_entity_association_tree_destroy_root(entityTree);
157 pldm_entity_association_tree_copy_root(bmcEntityTree,
158 entityTree);
159 this->sensorMap.clear();
160 this->responseReceived = false;
George Liuacf2c8c2021-05-10 14:08:52 +0800161 this->mergedHostParents = false;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500162 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500163 }
Patrick Williamsa6756622023-10-20 11:19:15 -0500164 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500165}
166
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500167void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500168{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500169 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500170 modifiedPDRRecordHandles.clear();
171
172 if (isHostPdrModified)
173 {
174 modifiedPDRRecordHandles = std::move(recordHandles);
175 }
176 else
177 {
178 pdrRecordHandles = std::move(recordHandles);
179 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500180
181 // Defer the actual fetch of PDRs from the host (by queuing the call on the
182 // main event loop). That way, we can respond to the platform event msg from
183 // the host firmware.
184 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
185 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
186 std::placeholders::_1));
187}
188
189void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
190{
Sampa Misrac0c79482021-06-02 08:01:54 -0500191 getHostPDR();
192}
193
194void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
195{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500196 pdrFetchEvent.reset();
197
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500198 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
199 PLDM_GET_PDR_REQ_BYTES);
200 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500201 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500202 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
203 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500204 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500205 recordHandle = modifiedPDRRecordHandles.front();
206 modifiedPDRRecordHandles.pop_front();
207 }
208 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
209 {
210 recordHandle = pdrRecordHandles.front();
211 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500212 }
213 else
214 {
215 recordHandle = nextRecordHandle;
216 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930217 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500218
Patrick Williams6da4f912023-05-10 07:50:53 -0500219 auto rc = encode_get_pdr_req(instanceId, recordHandle, 0,
220 PLDM_GET_FIRSTPART, UINT16_MAX, 0, request,
221 PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500222 if (rc != PLDM_SUCCESS)
223 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930224 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600225 error("Failed to encode_get_pdr_req, rc = {RC}", "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500226 return;
227 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500228
Sampa Misrac0c79482021-06-02 08:01:54 -0500229 rc = handler->registerRequest(
230 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
231 std::move(requestMsg),
232 std::move(std::bind_front(&HostPDRHandler::processHostPDRs, this)));
233 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500234 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600235 error("Failed to send the GetPDR request to Host");
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500236 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500237}
238
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600239int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
240 pdr::EventState state)
241{
242 auto rc = stateSensorHandler.eventAction(entry, state);
243 if (rc != PLDM_SUCCESS)
244 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600245 error("Failed to fetch and update D-bus property, rc = {RC}", "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600246 return rc;
247 }
248 return PLDM_SUCCESS;
249}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500250
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500251void HostPDRHandler::mergeEntityAssociations(
252 const std::vector<uint8_t>& pdr, [[maybe_unused]] const uint32_t& size,
253 [[maybe_unused]] const uint32_t& record_handle)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500254{
255 size_t numEntities{};
256 pldm_entity* entities = nullptr;
257 bool merged = false;
258 auto entityPdr = reinterpret_cast<pldm_pdr_entity_association*>(
259 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
260
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500261 if (oemPlatformHandler &&
262 oemPlatformHandler->checkRecordHandleInRange(record_handle))
263 {
264 // Adding the remote range PDRs to the repo before merging it
265 uint32_t handle = record_handle;
266 pldm_pdr_add_check(repo, pdr.data(), size, true, 0xFFFF, &handle);
267 }
268
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500269 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
270 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800271 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500272 {
George Liuacf2c8c2021-05-10 14:08:52 +0800273 pldm_entity_node* pNode = nullptr;
274 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500275 {
George Liuacf2c8c2021-05-10 14:08:52 +0800276 pNode = pldm_entity_association_tree_find_with_locality(
277 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500278 }
George Liuacf2c8c2021-05-10 14:08:52 +0800279 else
280 {
281 pNode = pldm_entity_association_tree_find_with_locality(
282 entityTree, &entities[0], true);
283 }
284 if (!pNode)
285 {
286 return;
287 }
288
George Liudf9a6d32020-12-22 16:27:16 +0800289 Entities entityAssoc;
290 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800291 for (size_t i = 1; i < numEntities; ++i)
292 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500293 bool isUpdateContainerId = true;
294 if (oemPlatformHandler)
295 {
296 isUpdateContainerId =
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600297 checkIfLogicalBitSet(entities[i].entity_container_id);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500298 }
George Liudf9a6d32020-12-22 16:27:16 +0800299 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800300 entityTree, &entities[i], entities[i].entity_instance_num,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500301 pNode, entityPdr->association_type, true, isUpdateContainerId,
302 0xFFFF);
303 if (!node)
304 {
305 continue;
306 }
George Liuacf2c8c2021-05-10 14:08:52 +0800307 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800308 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800309 }
310
311 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800312 if (merged)
313 {
314 entityAssociations.push_back(entityAssoc);
315 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500316 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500317
318 if (merged)
319 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500320 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500321 pldm_entity_node* node = nullptr;
322 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
323 if (node == nullptr)
324 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600325 error("could not find referrence of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500326 }
327 else
328 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500329 int rc = 0;
330 if (oemPlatformHandler)
331 {
332 auto record = oemPlatformHandler->fetchLastBMCRecord(repo);
333
334 uint32_t record_handle = pldm_pdr_get_record_handle(repo,
335 record);
336
337 rc =
338 pldm_entity_association_pdr_add_from_node_with_record_handle(
339 node, repo, &entities, numEntities, true,
340 TERMINUS_HANDLE, (record_handle + 1));
341 }
342 else
343 {
344 rc = pldm_entity_association_pdr_add_from_node_check(
345 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
346 }
347
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930348 if (rc)
349 {
350 error(
351 "Failed to add entity association PDR from node: {LIBPLDM_ERROR}",
352 "LIBPLDM_ERROR", rc);
353 }
Sampa Misra719ed392021-06-04 05:15:13 -0500354 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500355 }
Sampa Misra719ed392021-06-04 05:15:13 -0500356 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500357}
358
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500359void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
360 uint8_t eventDataFormat)
361{
362 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
363
364 // Extract from the PDR repo record handles of PDRs we want the host
365 // to pull up.
366 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
367 std::vector<uint8_t> numsOfChangeEntries(1);
368 std::vector<std::vector<ChangeEntry>> changeEntries(
369 numsOfChangeEntries.size());
370 for (auto pdrType : pdrTypes)
371 {
372 const pldm_pdr_record* record{};
373 do
374 {
375 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
376 nullptr, nullptr);
377 if (record && pldm_pdr_record_is_remote(record))
378 {
379 changeEntries[0].push_back(
380 pldm_pdr_get_record_handle(repo, record));
381 }
382 } while (record);
383 }
384 if (changeEntries.empty())
385 {
386 return;
387 }
388 numsOfChangeEntries[0] = changeEntries[0].size();
389
390 // Encode PLDM platform event msg to indicate a PDR repo change.
391 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
392 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
393 changeEntries[0].size() * sizeof(uint32_t);
394 std::vector<uint8_t> eventDataVec{};
395 eventDataVec.resize(maxSize);
396 auto eventData =
397 reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
398 eventDataVec.data());
399 size_t actualSize{};
400 auto firstEntry = changeEntries[0].data();
401 auto rc = encode_pldm_pdr_repository_chg_event_data(
402 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
403 &firstEntry, eventData, &actualSize, maxSize);
404 if (rc != PLDM_SUCCESS)
405 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600406 error("Failed to encode_pldm_pdr_repository_chg_event_data, rc = {RC}",
407 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500408 return;
409 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930410 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500411 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
412 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
413 actualSize);
414 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
415 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600416 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
417 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500418 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500419 if (rc != PLDM_SUCCESS)
420 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930421 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600422 error("Failed to encode_platform_event_message_req, rc = {RC}", "RC",
423 rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500424 return;
425 }
426
Patrick Williams6da4f912023-05-10 07:50:53 -0500427 auto platformEventMessageResponseHandler =
428 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700429 if (response == nullptr || !respMsgLen)
430 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600431 error(
432 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700433 return;
434 }
435
436 uint8_t completionCode{};
437 uint8_t status{};
438 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500439 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
440 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500441 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700442 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600443 error(
444 "Failed to decode_platform_event_message_resp: {RC}, cc = {CC}",
445 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Tom Joseph74f27c72021-05-16 07:58:53 -0700446 }
447 };
448
Sampa Misrac0c79482021-06-02 08:01:54 -0500449 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500450 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700451 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500452 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500453 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600454 error("Failed to send the PDR repository changed event request");
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500455 }
456}
457
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530458void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500459{
460 for (const auto& pdr : stateSensorPDRs)
461 {
462 SensorEntry sensorEntry{};
463 const auto& [terminusHandle, sensorID, sensorInfo] =
464 responder::pdr_utils::parseStateSensorPDR(pdr);
465 sensorEntry.sensorID = sensorID;
466 try
467 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530468 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500469 }
470 // If there is no mapping for terminusHandle assign the reserved TID
471 // value of 0xFF to indicate that.
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500472 catch (const std::out_of_range&)
Sampa Misra868c8792020-05-26 03:12:13 -0500473 {
474 sensorEntry.terminusID = PLDM_TID_RESERVED;
475 }
476 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
477 }
478}
479
Sampa Misrac0c79482021-06-02 08:01:54 -0500480void HostPDRHandler::processHostPDRs(mctp_eid_t /*eid*/,
481 const pldm_msg* response,
482 size_t respMsgLen)
483{
484 static bool merged = false;
485 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800486 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500487 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600488 uint8_t tlEid = 0;
489 bool tlValid = true;
490 uint32_t rh = 0;
491 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530492 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600493 uint8_t tid = 0;
494
Sampa Misrac0c79482021-06-02 08:01:54 -0500495 uint8_t completionCode{};
496 uint32_t nextDataTransferHandle{};
497 uint8_t transferFlag{};
498 uint16_t respCount{};
499 uint8_t transferCRC{};
500 if (response == nullptr || !respMsgLen)
501 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600502 error("Failed to receive response for the GetPDR command");
Sampa Misrac0c79482021-06-02 08:01:54 -0500503 return;
504 }
505
506 auto rc = decode_get_pdr_resp(
507 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
508 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
509 nullptr, 0, &transferCRC);
510 std::vector<uint8_t> responsePDRMsg;
511 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
512 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500513 if (rc != PLDM_SUCCESS)
514 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600515 error("Failed to decode_get_pdr_resp, rc = {RC}", "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500516 return;
517 }
518 else
519 {
520 std::vector<uint8_t> pdr(respCount, 0);
521 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
522 &nextRecordHandle, &nextDataTransferHandle,
523 &transferFlag, &respCount, pdr.data(),
524 respCount, &transferCRC);
525 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
526 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600527 error("Failed to decode_get_pdr_resp: rc = {RC}, cc = {CC}", "RC",
528 rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -0500529 return;
530 }
531 else
532 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600533 // when nextRecordHandle is 0, we need the recordHandle of the last
534 // PDR and not 0-1.
535 if (!nextRecordHandle)
536 {
537 rh = nextRecordHandle;
538 }
539 else
540 {
541 rh = nextRecordHandle - 1;
542 }
543
Sampa Misrac0c79482021-06-02 08:01:54 -0500544 auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600545 if (!rh)
546 {
547 rh = pdrHdr->record_handle;
548 }
549
Sampa Misrac0c79482021-06-02 08:01:54 -0500550 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
551 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500552 this->mergeEntityAssociations(pdr, respCount, rh);
Sampa Misrac0c79482021-06-02 08:01:54 -0500553 merged = true;
554 }
555 else
556 {
557 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
558 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530559 pdrTerminusHandle =
560 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500561 auto tlpdr =
562 reinterpret_cast<const pldm_terminus_locator_pdr*>(
563 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600564
565 terminusHandle = tlpdr->terminus_handle;
566 tid = tlpdr->tid;
567 auto terminus_locator_type = tlpdr->terminus_locator_type;
568 if (terminus_locator_type ==
569 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
570 {
571 auto locatorValue = reinterpret_cast<
572 const pldm_terminus_locator_type_mctp_eid*>(
573 tlpdr->terminus_locator_value);
574 tlEid = static_cast<uint8_t>(locatorValue->eid);
575 }
576 if (tlpdr->validity == 0)
577 {
578 tlValid = false;
579 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500580 for (const auto& terminusMap : tlPDRInfo)
581 {
582 if ((terminusHandle == (terminusMap.first)) &&
583 (get<1>(terminusMap.second) == tlEid) &&
584 (get<2>(terminusMap.second) == tlpdr->validity))
585 {
586 // TL PDR already present with same validity don't
587 // add the PDR to the repo just return
588 return;
589 }
590 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530591 tlPDRInfo.insert_or_assign(
592 tlpdr->terminus_handle,
593 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500594 }
595 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
596 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530597 pdrTerminusHandle =
598 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800599 updateContainerId<pldm_state_sensor_pdr>(entityTree, pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500600 stateSensorPDRs.emplace_back(pdr);
601 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530602 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
603 {
604 pdrTerminusHandle =
605 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800606 updateContainerId<pldm_pdr_fru_record_set>(entityTree, pdr);
George Liu682ee182020-12-25 15:24:33 +0800607 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530608 }
609 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
610 {
611 pdrTerminusHandle =
612 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800613 updateContainerId<pldm_state_effecter_pdr>(entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530614 }
615 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
616 {
617 pdrTerminusHandle =
618 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
619 pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800620 updateContainerId<pldm_numeric_effecter_value_pdr>(
621 entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530622 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600623 // if the TLPDR is invalid update the repo accordingly
624 if (!tlValid)
625 {
626 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
627 tlValid);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500628
629 if (!isHostUp())
630 {
631 // The terminus PDR becomes invalid when the terminus
632 // itself is down. We don't need to do PDR exchange in
633 // that case, so setting the next record handle to 0.
634 nextRecordHandle = 0;
635 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600636 }
637 else
638 {
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930639 rc = pldm_pdr_add_check(repo, pdr.data(), respCount, true,
640 pdrTerminusHandle, &rh);
641 if (rc)
642 {
643 // pldm_pdr_add() assert()ed on failure to add a PDR.
644 throw std::runtime_error("Failed to add PDR");
645 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600646 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500647 }
648 }
649 }
650 if (!nextRecordHandle)
651 {
George Liudf9a6d32020-12-22 16:27:16 +0800652 updateEntityAssociation(entityAssociations, entityTree, objPathMap);
653
Sampa Misrac0c79482021-06-02 08:01:54 -0500654 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530655 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800656 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600657 if (isHostUp())
658 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530659 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600660 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500661 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800662 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800663 entityAssociations.clear();
664
Sampa Misrac0c79482021-06-02 08:01:54 -0500665 if (merged)
666 {
667 merged = false;
668 deferredPDRRepoChgEvent =
669 std::make_unique<sdeventplus::source::Defer>(
670 event,
671 std::bind(
672 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
673 this, std::placeholders::_1));
674 }
675 }
676 else
677 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500678 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
679 {
680 isHostPdrModified = false;
681 }
682 else
683 {
684 deferredFetchPDREvent =
685 std::make_unique<sdeventplus::source::Defer>(
686 event,
687 std::bind(
688 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
689 this, nextRecordHandle, std::placeholders::_1));
690 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500691 }
692}
693
694void HostPDRHandler::_processPDRRepoChgEvent(
695 sdeventplus::source::EventBase& /*source */)
696{
697 deferredPDRRepoChgEvent.reset();
698 this->sendPDRRepositoryChgEvent(
699 std::move(std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION)),
700 FORMAT_IS_PDR_HANDLES);
701}
702
703void HostPDRHandler::_processFetchPDREvent(
704 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
705{
706 deferredFetchPDREvent.reset();
707 if (!this->pdrRecordHandles.empty())
708 {
709 nextRecordHandle = this->pdrRecordHandles.front();
710 this->pdrRecordHandles.pop_front();
711 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500712 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
713 {
714 nextRecordHandle = this->modifiedPDRRecordHandles.front();
715 this->modifiedPDRRecordHandles.pop_front();
716 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500717 this->getHostPDR(nextRecordHandle);
718}
719
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500720void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530721{
sampmisr6decfc12021-03-02 11:07:36 +0530722 responseReceived = false;
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930723 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500724 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
725 PLDM_GET_VERSION_REQ_BYTES);
726 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
727 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
728 PLDM_BASE, request);
729 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530730 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600731 error("GetPLDMVersion encode failure. PLDM error code = {RC}", "RC",
732 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930733 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530734 return;
735 }
736
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500737 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
738 const pldm_msg* response,
739 size_t respMsgLen) {
740 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530741 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600742 error(
743 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530744 return;
745 }
Riya Dixit49cfb132023-03-02 04:26:53 -0600746 info("Getting the response. PLDM RC = {RC}", "RC", lg2::hex,
747 static_cast<uint16_t>(response->payload[0]));
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500748 this->responseReceived = true;
749 getHostPDR();
sampmisr6decfc12021-03-02 11:07:36 +0530750 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500751 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
752 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
753 std::move(getPLDMVersionHandler));
754 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530755 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600756 error("Failed to discover Host state. Assuming Host as off");
sampmisr6decfc12021-03-02 11:07:36 +0530757 }
758}
759
760bool HostPDRHandler::isHostUp()
761{
762 return responseReceived;
763}
764
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530765void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600766{
767 for (const auto& stateSensorPDR : stateSensorPDRs)
768 {
769 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
770 stateSensorPDR.data());
771
772 if (!pdr)
773 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600774 error("Failed to get State sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600775 pldm::utils::reportError(
Pavithra Barithayad28f08c2021-12-15 03:37:14 -0600776 "xyz.openbmc_project.PLDM.Error.SetHostSensorState.GetStateSensorPDRFail");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600777 return;
778 }
779
780 uint16_t sensorId = pdr->sensor_id;
781
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530782 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600783 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530784 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600785 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530786 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600787 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530788 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600789 }
790
791 bitfield8_t sensorRearm;
792 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530793 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600794
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930795 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600796 std::vector<uint8_t> requestMsg(
797 sizeof(pldm_msg_hdr) +
798 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
799 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
800 auto rc = encode_get_state_sensor_readings_req(
801 instanceId, sensorId, sensorRearm, 0, request);
802
803 if (rc != PLDM_SUCCESS)
804 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930805 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600806 error(
807 "Failed to encode_get_state_sensor_readings_req, rc = {RC}",
808 "RC", rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600809 pldm::utils::reportError(
Pavithra Barithayad28f08c2021-12-15 03:37:14 -0600810 "xyz.openbmc_project.PLDM.Error.SetHostSensorState.EncodeStateSensorFail");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600811 return;
812 }
813
Patrick Williams6da4f912023-05-10 07:50:53 -0500814 auto getStateSensorReadingRespHandler =
815 [=, this](mctp_eid_t /*eid*/, const pldm_msg* response,
816 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600817 if (response == nullptr || !respMsgLen)
818 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600819 error(
820 "Failed to receive response for getStateSensorReading command");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600821 return;
822 }
823 std::array<get_sensor_state_field, 8> stateField{};
824 uint8_t completionCode = 0;
825 uint8_t comp_sensor_count = 0;
826
827 auto rc = decode_get_state_sensor_readings_resp(
828 response, respMsgLen, &completionCode,
829 &comp_sensor_count, stateField.data());
830
831 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
832 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600833 error(
834 "Failed to decode_get_state_sensor_readings_resp, rc = {RC} cc = {CC}",
835 "RC", rc, "CC",
836 static_cast<unsigned>(completionCode));
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600837 }
838
839 uint8_t eventState;
840 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600841
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500842 for (uint8_t sensorOffset = 0;
843 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600844 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500845 eventState = stateField[sensorOffset].present_state;
846 previousEventState =
847 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600848
849 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
850 eventState,
851 previousEventState);
852
853 SensorEntry sensorEntry{tid, sensorId};
854
855 pldm::pdr::EntityInfo entityInfo{};
856 pldm::pdr::CompositeSensorStates
857 compositeSensorStates{};
Sagar Srinivase3607a32024-02-16 03:50:53 -0600858 std::vector<pldm::pdr::StateSetId> stateSetIds{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600859
860 try
861 {
Sagar Srinivase3607a32024-02-16 03:50:53 -0600862 std::tie(entityInfo, compositeSensorStates,
863 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600864 lookupSensorInfo(sensorEntry);
865 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500866 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600867 {
868 try
869 {
870 sensorEntry.terminusID = PLDM_TID_RESERVED;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600871 std::tie(entityInfo, compositeSensorStates,
872 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600873 lookupSensorInfo(sensorEntry);
874 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500875 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600876 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600877 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600878 }
879 }
880
881 if (sensorOffset > compositeSensorStates.size())
882 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600883 error("Error Invalid data, Invalid sensor offset");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600884 return;
885 }
886
887 const auto& possibleStates =
888 compositeSensorStates[sensorOffset];
889 if (possibleStates.find(eventState) ==
890 possibleStates.end())
891 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600892 error("Error invalid_data, Invalid event state");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600893 return;
894 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500895 const auto& [containerId, entityType,
896 entityInstance] = entityInfo;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600897 auto stateSetId = stateSetIds[sensorOffset];
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600898 pldm::responder::events::StateSensorEntry
899 stateSensorEntry{containerId, entityType,
Sagar Srinivase3607a32024-02-16 03:50:53 -0600900 entityInstance, sensorOffset,
901 stateSetId};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600902 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(
Manojkiran Eda33a9cd02024-01-22 11:06:59 +05301033 responsePtr, respMsgLen, &cc, &next_data_transfer_handle,
1034 &transfer_flag, fru_record_table_data.data(),
1035 &fru_record_table_length);
George Liu682ee182020-12-25 15:24:33 +08001036
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