blob: 3f3b96480ee250f111bb4151992ac50d66d3c8f4 [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;
Patrick Williams84b790c2022-07-22 19:26:56 -0500101 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500102 pldm::utils::DBusHandler::getBus(),
103 propertiesChanged("/xyz/openbmc_project/state/host0",
104 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -0500105 [this, repo, entityTree, bmcEntityTree](sdbusplus::message_t& msg) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500106 DbusChangedProps props{};
107 std::string intf;
108 msg.read(intf, props);
109 const auto itr = props.find("CurrentHostState");
110 if (itr != props.end())
111 {
112 PropertyValue value = itr->second;
113 auto propVal = std::get<std::string>(value);
114 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500115 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500116 // Delete all the remote terminus information
117 std::erase_if(tlPDRInfo, [](const auto& item) {
118 auto const& [key, value] = item;
119 return key != TERMINUS_HANDLE;
120 });
121 pldm_pdr_remove_remote_pdrs(repo);
122 pldm_entity_association_tree_destroy_root(entityTree);
123 pldm_entity_association_tree_copy_root(bmcEntityTree,
124 entityTree);
125 this->sensorMap.clear();
126 this->responseReceived = false;
George Liuacf2c8c2021-05-10 14:08:52 +0800127 this->mergedHostParents = false;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500128 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500129 }
Patrick Williamsa6756622023-10-20 11:19:15 -0500130 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500131}
132
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500133void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500134{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500135 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500136 modifiedPDRRecordHandles.clear();
137
138 if (isHostPdrModified)
139 {
140 modifiedPDRRecordHandles = std::move(recordHandles);
141 }
142 else
143 {
144 pdrRecordHandles = std::move(recordHandles);
145 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500146
147 // Defer the actual fetch of PDRs from the host (by queuing the call on the
148 // main event loop). That way, we can respond to the platform event msg from
149 // the host firmware.
150 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
151 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
152 std::placeholders::_1));
153}
154
155void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
156{
Sampa Misrac0c79482021-06-02 08:01:54 -0500157 getHostPDR();
158}
159
160void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
161{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500162 pdrFetchEvent.reset();
163
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500164 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
165 PLDM_GET_PDR_REQ_BYTES);
166 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500167 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500168 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
169 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500170 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500171 recordHandle = modifiedPDRRecordHandles.front();
172 modifiedPDRRecordHandles.pop_front();
173 }
174 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
175 {
176 recordHandle = pdrRecordHandles.front();
177 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500178 }
179 else
180 {
181 recordHandle = nextRecordHandle;
182 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930183 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500184
Patrick Williams6da4f912023-05-10 07:50:53 -0500185 auto rc = encode_get_pdr_req(instanceId, recordHandle, 0,
186 PLDM_GET_FIRSTPART, UINT16_MAX, 0, request,
187 PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500188 if (rc != PLDM_SUCCESS)
189 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930190 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500191 error("Failed to encode get pdr request, response code '{RC}'", "RC",
192 rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500193 return;
194 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500195
Sampa Misrac0c79482021-06-02 08:01:54 -0500196 rc = handler->registerRequest(
197 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
198 std::move(requestMsg),
199 std::move(std::bind_front(&HostPDRHandler::processHostPDRs, this)));
200 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500201 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500202 error(
203 "Failed to send the getPDR request to remote terminus, response code '{RC}'",
204 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500205 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500206}
207
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600208int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
209 pdr::EventState state)
210{
211 auto rc = stateSensorHandler.eventAction(entry, state);
212 if (rc != PLDM_SUCCESS)
213 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500214 error("Failed to fetch and update D-bus property, response code '{RC}'",
215 "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600216 return rc;
217 }
218 return PLDM_SUCCESS;
219}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500220
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500221void HostPDRHandler::mergeEntityAssociations(
222 const std::vector<uint8_t>& pdr, [[maybe_unused]] const uint32_t& size,
223 [[maybe_unused]] const uint32_t& record_handle)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500224{
225 size_t numEntities{};
226 pldm_entity* entities = nullptr;
227 bool merged = false;
228 auto entityPdr = reinterpret_cast<pldm_pdr_entity_association*>(
229 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
230
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500231 if (oemPlatformHandler &&
232 oemPlatformHandler->checkRecordHandleInRange(record_handle))
233 {
234 // Adding the remote range PDRs to the repo before merging it
235 uint32_t handle = record_handle;
236 pldm_pdr_add_check(repo, pdr.data(), size, true, 0xFFFF, &handle);
237 }
238
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500239 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
240 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800241 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500242 {
George Liuacf2c8c2021-05-10 14:08:52 +0800243 pldm_entity_node* pNode = nullptr;
244 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500245 {
George Liuacf2c8c2021-05-10 14:08:52 +0800246 pNode = pldm_entity_association_tree_find_with_locality(
247 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500248 }
George Liuacf2c8c2021-05-10 14:08:52 +0800249 else
250 {
251 pNode = pldm_entity_association_tree_find_with_locality(
252 entityTree, &entities[0], true);
253 }
254 if (!pNode)
255 {
256 return;
257 }
258
George Liudf9a6d32020-12-22 16:27:16 +0800259 Entities entityAssoc;
260 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800261 for (size_t i = 1; i < numEntities; ++i)
262 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500263 bool isUpdateContainerId = true;
264 if (oemPlatformHandler)
265 {
266 isUpdateContainerId =
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600267 checkIfLogicalBitSet(entities[i].entity_container_id);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500268 }
George Liudf9a6d32020-12-22 16:27:16 +0800269 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800270 entityTree, &entities[i], entities[i].entity_instance_num,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500271 pNode, entityPdr->association_type, true, isUpdateContainerId,
272 0xFFFF);
273 if (!node)
274 {
275 continue;
276 }
George Liuacf2c8c2021-05-10 14:08:52 +0800277 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800278 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800279 }
280
281 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800282 if (merged)
283 {
284 entityAssociations.push_back(entityAssoc);
285 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500286 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500287
288 if (merged)
289 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500290 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500291 pldm_entity_node* node = nullptr;
292 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
293 if (node == nullptr)
294 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500295 error("Failed to find referrence of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500296 }
297 else
298 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500299 int rc = 0;
300 if (oemPlatformHandler)
301 {
302 auto record = oemPlatformHandler->fetchLastBMCRecord(repo);
303
304 uint32_t record_handle = pldm_pdr_get_record_handle(repo,
305 record);
306
307 rc =
308 pldm_entity_association_pdr_add_from_node_with_record_handle(
309 node, repo, &entities, numEntities, true,
310 TERMINUS_HANDLE, (record_handle + 1));
311 }
312 else
313 {
314 rc = pldm_entity_association_pdr_add_from_node_check(
315 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
316 }
317
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930318 if (rc)
319 {
320 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500321 "Failed to add entity association PDR from node, response code '{RC}'",
322 "RC", rc);
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930323 }
Sampa Misra719ed392021-06-04 05:15:13 -0500324 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500325 }
Sampa Misra719ed392021-06-04 05:15:13 -0500326 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500327}
328
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500329void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
330 uint8_t eventDataFormat)
331{
332 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
333
334 // Extract from the PDR repo record handles of PDRs we want the host
335 // to pull up.
336 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
337 std::vector<uint8_t> numsOfChangeEntries(1);
338 std::vector<std::vector<ChangeEntry>> changeEntries(
339 numsOfChangeEntries.size());
340 for (auto pdrType : pdrTypes)
341 {
342 const pldm_pdr_record* record{};
343 do
344 {
345 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
346 nullptr, nullptr);
347 if (record && pldm_pdr_record_is_remote(record))
348 {
349 changeEntries[0].push_back(
350 pldm_pdr_get_record_handle(repo, record));
351 }
352 } while (record);
353 }
354 if (changeEntries.empty())
355 {
356 return;
357 }
358 numsOfChangeEntries[0] = changeEntries[0].size();
359
360 // Encode PLDM platform event msg to indicate a PDR repo change.
361 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
362 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
363 changeEntries[0].size() * sizeof(uint32_t);
364 std::vector<uint8_t> eventDataVec{};
365 eventDataVec.resize(maxSize);
366 auto eventData =
367 reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
368 eventDataVec.data());
369 size_t actualSize{};
370 auto firstEntry = changeEntries[0].data();
371 auto rc = encode_pldm_pdr_repository_chg_event_data(
372 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
373 &firstEntry, eventData, &actualSize, maxSize);
374 if (rc != PLDM_SUCCESS)
375 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500376 error(
377 "Failed to encode pldm pdr repository change event data, response code '{RC}'",
378 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500379 return;
380 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930381 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500382 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
383 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
384 actualSize);
385 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
386 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600387 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
388 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500389 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500390 if (rc != PLDM_SUCCESS)
391 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930392 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500393 error(
394 "Failed to encode platform event message request, response code '{RC}'",
395 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500396 return;
397 }
398
Patrick Williams6da4f912023-05-10 07:50:53 -0500399 auto platformEventMessageResponseHandler =
400 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700401 if (response == nullptr || !respMsgLen)
402 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600403 error(
404 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700405 return;
406 }
407
408 uint8_t completionCode{};
409 uint8_t status{};
410 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500411 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
412 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500413 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700414 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600415 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500416 "Failed to decode platform event message response, response code '{RC}' and completion code '{CC}'",
417 "RC", rc, "CC", completionCode);
Tom Joseph74f27c72021-05-16 07:58:53 -0700418 }
419 };
420
Sampa Misrac0c79482021-06-02 08:01:54 -0500421 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500422 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700423 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500424 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500425 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500426 error(
427 "Failed to send the PDR repository changed event request, response code '{RC}'",
428 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500429 }
430}
431
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530432void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500433{
434 for (const auto& pdr : stateSensorPDRs)
435 {
436 SensorEntry sensorEntry{};
437 const auto& [terminusHandle, sensorID, sensorInfo] =
438 responder::pdr_utils::parseStateSensorPDR(pdr);
439 sensorEntry.sensorID = sensorID;
440 try
441 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530442 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500443 }
444 // If there is no mapping for terminusHandle assign the reserved TID
445 // value of 0xFF to indicate that.
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500446 catch (const std::out_of_range&)
Sampa Misra868c8792020-05-26 03:12:13 -0500447 {
448 sensorEntry.terminusID = PLDM_TID_RESERVED;
449 }
450 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
451 }
452}
453
Sampa Misrac0c79482021-06-02 08:01:54 -0500454void HostPDRHandler::processHostPDRs(mctp_eid_t /*eid*/,
455 const pldm_msg* response,
456 size_t respMsgLen)
457{
458 static bool merged = false;
459 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800460 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500461 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600462 uint8_t tlEid = 0;
463 bool tlValid = true;
464 uint32_t rh = 0;
465 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530466 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600467 uint8_t tid = 0;
468
Sampa Misrac0c79482021-06-02 08:01:54 -0500469 uint8_t completionCode{};
470 uint32_t nextDataTransferHandle{};
471 uint8_t transferFlag{};
472 uint16_t respCount{};
473 uint8_t transferCRC{};
474 if (response == nullptr || !respMsgLen)
475 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600476 error("Failed to receive response for the GetPDR command");
Sampa Misrac0c79482021-06-02 08:01:54 -0500477 return;
478 }
479
480 auto rc = decode_get_pdr_resp(
481 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
482 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
483 nullptr, 0, &transferCRC);
484 std::vector<uint8_t> responsePDRMsg;
485 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
486 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500487 if (rc != PLDM_SUCCESS)
488 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500489 error(
490 "Failed to decode getPDR response for next record handle '{NEXT_RECORD_HANDLE}', response code '{RC}'",
491 "NEXT_RECORD_HANDLE", nextRecordHandle, "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500492 return;
493 }
494 else
495 {
496 std::vector<uint8_t> pdr(respCount, 0);
497 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
498 &nextRecordHandle, &nextDataTransferHandle,
499 &transferFlag, &respCount, pdr.data(),
500 respCount, &transferCRC);
501 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
502 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500503 error(
504 "Failed to decode getPDR response for next record handle '{NEXT_RECORD_HANDLE}', next data transfer handle '{DATA_TRANSFER_HANDLE}' and transfer flag '{FLAG}', response code '{RC}' and completion code '{CC}'",
505 "NEXT_RECORD_HANDLE", nextRecordHandle, "DATA_TRANSFER_HANDLE",
506 nextDataTransferHandle, "FLAG", transferFlag, "RC", rc, "CC",
507 completionCode);
Sampa Misrac0c79482021-06-02 08:01:54 -0500508 return;
509 }
510 else
511 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600512 // when nextRecordHandle is 0, we need the recordHandle of the last
513 // PDR and not 0-1.
514 if (!nextRecordHandle)
515 {
516 rh = nextRecordHandle;
517 }
518 else
519 {
520 rh = nextRecordHandle - 1;
521 }
522
Sampa Misrac0c79482021-06-02 08:01:54 -0500523 auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600524 if (!rh)
525 {
526 rh = pdrHdr->record_handle;
527 }
528
Sampa Misrac0c79482021-06-02 08:01:54 -0500529 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
530 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500531 this->mergeEntityAssociations(pdr, respCount, rh);
Sampa Misrac0c79482021-06-02 08:01:54 -0500532 merged = true;
533 }
534 else
535 {
536 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
537 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530538 pdrTerminusHandle =
539 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500540 auto tlpdr =
541 reinterpret_cast<const pldm_terminus_locator_pdr*>(
542 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600543
544 terminusHandle = tlpdr->terminus_handle;
545 tid = tlpdr->tid;
546 auto terminus_locator_type = tlpdr->terminus_locator_type;
547 if (terminus_locator_type ==
548 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
549 {
550 auto locatorValue = reinterpret_cast<
551 const pldm_terminus_locator_type_mctp_eid*>(
552 tlpdr->terminus_locator_value);
553 tlEid = static_cast<uint8_t>(locatorValue->eid);
554 }
555 if (tlpdr->validity == 0)
556 {
557 tlValid = false;
558 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500559 for (const auto& terminusMap : tlPDRInfo)
560 {
561 if ((terminusHandle == (terminusMap.first)) &&
562 (get<1>(terminusMap.second) == tlEid) &&
563 (get<2>(terminusMap.second) == tlpdr->validity))
564 {
565 // TL PDR already present with same validity don't
566 // add the PDR to the repo just return
567 return;
568 }
569 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530570 tlPDRInfo.insert_or_assign(
571 tlpdr->terminus_handle,
572 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500573 }
574 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
575 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530576 pdrTerminusHandle =
577 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800578 updateContainerId<pldm_state_sensor_pdr>(entityTree, pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500579 stateSensorPDRs.emplace_back(pdr);
580 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530581 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
582 {
583 pdrTerminusHandle =
584 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800585 updateContainerId<pldm_pdr_fru_record_set>(entityTree, pdr);
George Liu682ee182020-12-25 15:24:33 +0800586 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530587 }
588 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
589 {
590 pdrTerminusHandle =
591 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800592 updateContainerId<pldm_state_effecter_pdr>(entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530593 }
594 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
595 {
596 pdrTerminusHandle =
597 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
598 pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800599 updateContainerId<pldm_numeric_effecter_value_pdr>(
600 entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530601 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600602 // if the TLPDR is invalid update the repo accordingly
603 if (!tlValid)
604 {
605 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
606 tlValid);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500607
608 if (!isHostUp())
609 {
610 // The terminus PDR becomes invalid when the terminus
611 // itself is down. We don't need to do PDR exchange in
612 // that case, so setting the next record handle to 0.
613 nextRecordHandle = 0;
614 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600615 }
616 else
617 {
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930618 rc = pldm_pdr_add_check(repo, pdr.data(), respCount, true,
619 pdrTerminusHandle, &rh);
620 if (rc)
621 {
622 // pldm_pdr_add() assert()ed on failure to add a PDR.
623 throw std::runtime_error("Failed to add PDR");
624 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600625 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500626 }
627 }
628 }
629 if (!nextRecordHandle)
630 {
George Liudf9a6d32020-12-22 16:27:16 +0800631 updateEntityAssociation(entityAssociations, entityTree, objPathMap);
632
Sampa Misrac0c79482021-06-02 08:01:54 -0500633 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530634 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800635 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600636 if (isHostUp())
637 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530638 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600639 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500640 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800641 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800642 entityAssociations.clear();
643
Sampa Misrac0c79482021-06-02 08:01:54 -0500644 if (merged)
645 {
646 merged = false;
647 deferredPDRRepoChgEvent =
648 std::make_unique<sdeventplus::source::Defer>(
649 event,
650 std::bind(
651 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
652 this, std::placeholders::_1));
653 }
654 }
655 else
656 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500657 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
658 {
659 isHostPdrModified = false;
660 }
661 else
662 {
663 deferredFetchPDREvent =
664 std::make_unique<sdeventplus::source::Defer>(
665 event,
666 std::bind(
667 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
668 this, nextRecordHandle, std::placeholders::_1));
669 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500670 }
671}
672
673void HostPDRHandler::_processPDRRepoChgEvent(
674 sdeventplus::source::EventBase& /*source */)
675{
676 deferredPDRRepoChgEvent.reset();
677 this->sendPDRRepositoryChgEvent(
678 std::move(std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION)),
679 FORMAT_IS_PDR_HANDLES);
680}
681
682void HostPDRHandler::_processFetchPDREvent(
683 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
684{
685 deferredFetchPDREvent.reset();
686 if (!this->pdrRecordHandles.empty())
687 {
688 nextRecordHandle = this->pdrRecordHandles.front();
689 this->pdrRecordHandles.pop_front();
690 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500691 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
692 {
693 nextRecordHandle = this->modifiedPDRRecordHandles.front();
694 this->modifiedPDRRecordHandles.pop_front();
695 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500696 this->getHostPDR(nextRecordHandle);
697}
698
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500699void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530700{
sampmisr6decfc12021-03-02 11:07:36 +0530701 responseReceived = false;
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930702 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500703 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
704 PLDM_GET_VERSION_REQ_BYTES);
705 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
706 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
707 PLDM_BASE, request);
708 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530709 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500710 error("Failed to encode GetPLDMVersion, response code {RC}", "RC",
Riya Dixit49cfb132023-03-02 04:26:53 -0600711 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930712 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530713 return;
714 }
715
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500716 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
717 const pldm_msg* response,
718 size_t respMsgLen) {
719 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530720 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600721 error(
722 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530723 return;
724 }
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500725 info("Getting the response code '{RC}'", "RC", lg2::hex,
Riya Dixit49cfb132023-03-02 04:26:53 -0600726 static_cast<uint16_t>(response->payload[0]));
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500727 this->responseReceived = true;
728 getHostPDR();
sampmisr6decfc12021-03-02 11:07:36 +0530729 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500730 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
731 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
732 std::move(getPLDMVersionHandler));
733 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530734 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500735 error(
736 "Failed to discover remote terminus state. Assuming remote terminus as off");
sampmisr6decfc12021-03-02 11:07:36 +0530737 }
738}
739
740bool HostPDRHandler::isHostUp()
741{
742 return responseReceived;
743}
744
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530745void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600746{
747 for (const auto& stateSensorPDR : stateSensorPDRs)
748 {
749 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
750 stateSensorPDR.data());
751
752 if (!pdr)
753 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500754 error("Failed to get state sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600755 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530756 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600757 return;
758 }
759
760 uint16_t sensorId = pdr->sensor_id;
761
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530762 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600763 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530764 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600765 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530766 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600767 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530768 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600769 }
770
771 bitfield8_t sensorRearm;
772 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530773 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600774
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930775 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600776 std::vector<uint8_t> requestMsg(
777 sizeof(pldm_msg_hdr) +
778 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
779 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
780 auto rc = encode_get_state_sensor_readings_req(
781 instanceId, sensorId, sensorRearm, 0, request);
782
783 if (rc != PLDM_SUCCESS)
784 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930785 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600786 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500787 "Failed to encode get state sensor readings request for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
788 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
789 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600790 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530791 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600792 return;
793 }
794
Patrick Williams6da4f912023-05-10 07:50:53 -0500795 auto getStateSensorReadingRespHandler =
796 [=, this](mctp_eid_t /*eid*/, const pldm_msg* response,
797 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600798 if (response == nullptr || !respMsgLen)
799 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600800 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500801 "Failed to receive response for get state sensor reading command for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}'",
802 "SENSOR_ID", sensorId, "INSTANCE", instanceId);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600803 return;
804 }
805 std::array<get_sensor_state_field, 8> stateField{};
806 uint8_t completionCode = 0;
807 uint8_t comp_sensor_count = 0;
808
809 auto rc = decode_get_state_sensor_readings_resp(
810 response, respMsgLen, &completionCode,
811 &comp_sensor_count, stateField.data());
812
813 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
814 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600815 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500816 "Failed to decode get state sensor readings response for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code'{RC}' and completion code '{CC}'",
817 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
818 rc, "CC", completionCode);
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530819 pldm::utils::reportError(
820 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600821 }
822
823 uint8_t eventState;
824 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600825
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500826 for (uint8_t sensorOffset = 0;
827 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600828 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500829 eventState = stateField[sensorOffset].present_state;
830 previousEventState =
831 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600832
833 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
834 eventState,
835 previousEventState);
836
837 SensorEntry sensorEntry{tid, sensorId};
838
839 pldm::pdr::EntityInfo entityInfo{};
840 pldm::pdr::CompositeSensorStates
841 compositeSensorStates{};
Sagar Srinivase3607a32024-02-16 03:50:53 -0600842 std::vector<pldm::pdr::StateSetId> stateSetIds{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600843
844 try
845 {
Sagar Srinivase3607a32024-02-16 03:50:53 -0600846 std::tie(entityInfo, compositeSensorStates,
847 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600848 lookupSensorInfo(sensorEntry);
849 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500850 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600851 {
852 try
853 {
854 sensorEntry.terminusID = PLDM_TID_RESERVED;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600855 std::tie(entityInfo, compositeSensorStates,
856 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600857 lookupSensorInfo(sensorEntry);
858 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500859 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600860 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600861 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600862 }
863 }
864
Manojkiran Eda07a07e22024-04-24 19:15:10 +0530865 if ((compositeSensorStates.size() > 1) &&
866 (sensorOffset > (compositeSensorStates.size() - 1)))
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600867 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500868 error(
869 "Error Invalid data, Invalid sensor offset '{SENSOR_OFFSET}'",
870 "SENSOR_OFFSET", sensorOffset);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600871 return;
872 }
873
874 const auto& possibleStates =
875 compositeSensorStates[sensorOffset];
876 if (possibleStates.find(eventState) ==
877 possibleStates.end())
878 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500879 error(
880 "Error invalid_data, Invalid event state '{STATE}'",
881 "STATE", eventState);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600882 return;
883 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500884 const auto& [containerId, entityType,
885 entityInstance] = entityInfo;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600886 auto stateSetId = stateSetIds[sensorOffset];
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600887 pldm::responder::events::StateSensorEntry
888 stateSensorEntry{containerId, entityType,
Sagar Srinivase3607a32024-02-16 03:50:53 -0600889 entityInstance, sensorOffset,
890 stateSetId};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600891 handleStateSensorEvent(stateSensorEntry, eventState);
892 }
893 };
894
895 rc = handler->registerRequest(
896 mctp_eid, instanceId, PLDM_PLATFORM,
897 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg),
898 std::move(getStateSensorReadingRespHandler));
899
900 if (rc != PLDM_SUCCESS)
901 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600902 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500903 "Failed to send request to get state sensor reading on remote terminus for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
904 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
905 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600906 }
907 }
908 }
909 }
910}
George Liu682ee182020-12-25 15:24:33 +0800911
912void HostPDRHandler::getFRURecordTableMetadataByRemote(
913 const PDRList& fruRecordSetPDRs)
914{
915 auto instanceId = instanceIdDb.next(mctp_eid);
916 std::vector<uint8_t> requestMsg(
917 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
918
919 // GetFruRecordTableMetadata
920 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
921 auto rc = encode_get_fru_record_table_metadata_req(
922 instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
923 if (rc != PLDM_SUCCESS)
924 {
925 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500926 error(
927 "Failed to encode get fru record table metadata request, response code '{RC}'",
George Liu682ee182020-12-25 15:24:33 +0800928 "RC", lg2::hex, rc);
929 return;
930 }
931
932 auto getFruRecordTableMetadataResponseHandler =
933 [this, fruRecordSetPDRs](mctp_eid_t /*eid*/, const pldm_msg* response,
934 size_t respMsgLen) {
935 if (response == nullptr || !respMsgLen)
936 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500937 error(
938 "Failed to receive response for the get fru record table metadata");
George Liu682ee182020-12-25 15:24:33 +0800939 return;
940 }
941
942 uint8_t cc = 0;
943 uint8_t fru_data_major_version, fru_data_minor_version;
944 uint32_t fru_table_maximum_size, fru_table_length;
945 uint16_t total_record_set_identifiers;
946 uint16_t total;
947 uint32_t checksum;
948
949 auto rc = decode_get_fru_record_table_metadata_resp(
950 response, respMsgLen, &cc, &fru_data_major_version,
951 &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
952 &total_record_set_identifiers, &total, &checksum);
953
954 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
955 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500956 error(
957 "Failed to decode get fru record table metadata response, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +0800958 "RC", lg2::hex, rc, "CC", cc);
959 return;
960 }
961
962 // pass total to getFRURecordTableByRemote
963 this->getFRURecordTableByRemote(fruRecordSetPDRs, total);
964 };
965
966 rc = handler->registerRequest(
967 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA,
968 std::move(requestMsg),
969 std::move(getFruRecordTableMetadataResponseHandler));
970 if (rc != PLDM_SUCCESS)
971 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500972 error(
973 "Failed to send the the set state effecter states request, response code '{RC}'",
974 "RC", rc);
George Liu682ee182020-12-25 15:24:33 +0800975 }
976
977 return;
978}
979
980void HostPDRHandler::getFRURecordTableByRemote(const PDRList& fruRecordSetPDRs,
981 uint16_t totalTableRecords)
982{
983 fruRecordData.clear();
984
985 if (!totalTableRecords)
986 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500987 error("Failed to get fru record table");
George Liu682ee182020-12-25 15:24:33 +0800988 return;
989 }
990
991 auto instanceId = instanceIdDb.next(mctp_eid);
992 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
993 PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
994
995 // send the getFruRecordTable command
996 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
997 auto rc = encode_get_fru_record_table_req(
998 instanceId, 0, PLDM_GET_FIRSTPART, request,
999 requestMsg.size() - sizeof(pldm_msg_hdr));
1000 if (rc != PLDM_SUCCESS)
1001 {
1002 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001003 error(
1004 "Failed to encode get fru record table request, response code '{RC}'",
1005 "RC", lg2::hex, rc);
George Liu682ee182020-12-25 15:24:33 +08001006 return;
1007 }
1008
1009 auto getFruRecordTableResponseHandler =
1010 [totalTableRecords, this, fruRecordSetPDRs](
1011 mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
1012 if (response == nullptr || !respMsgLen)
1013 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001014 error("Failed to receive response for the get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001015 return;
1016 }
1017
1018 uint8_t cc = 0;
1019 uint32_t next_data_transfer_handle = 0;
1020 uint8_t transfer_flag = 0;
1021 size_t fru_record_table_length = 0;
1022 std::vector<uint8_t> fru_record_table_data(respMsgLen -
1023 sizeof(pldm_msg_hdr));
1024 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
1025 auto rc = decode_get_fru_record_table_resp(
Manojkiran Eda33a9cd02024-01-22 11:06:59 +05301026 responsePtr, respMsgLen, &cc, &next_data_transfer_handle,
1027 &transfer_flag, fru_record_table_data.data(),
1028 &fru_record_table_length);
George Liu682ee182020-12-25 15:24:33 +08001029
1030 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
1031 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001032 error(
1033 "Failed to decode get fru record table resp, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +08001034 "RC", lg2::hex, rc, "CC", cc);
1035 return;
1036 }
1037
1038 fruRecordData = responder::pdr_utils::parseFruRecordTable(
1039 fru_record_table_data.data(), fru_record_table_length);
1040
1041 if (totalTableRecords != fruRecordData.size())
1042 {
1043 fruRecordData.clear();
1044
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001045 error("Failed to parse fru recrod data format.");
George Liu682ee182020-12-25 15:24:33 +08001046 return;
1047 }
1048
1049 this->setFRUDataOnDBus(fruRecordSetPDRs, fruRecordData);
1050 };
1051
1052 rc = handler->registerRequest(
1053 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE,
1054 std::move(requestMsg), std::move(getFruRecordTableResponseHandler));
1055 if (rc != PLDM_SUCCESS)
1056 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001057 error("Failed to send the the set state effecter states request");
George Liu682ee182020-12-25 15:24:33 +08001058 }
1059}
1060
1061std::optional<uint16_t> HostPDRHandler::getRSI(const PDRList& fruRecordSetPDRs,
1062 const pldm_entity& entity)
1063{
1064 for (const auto& pdr : fruRecordSetPDRs)
1065 {
1066 auto fruPdr = reinterpret_cast<const pldm_pdr_fru_record_set*>(
1067 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
1068
1069 if (fruPdr->entity_type == entity.entity_type &&
Sagar Srinivasebf8bb52023-10-06 01:15:55 -05001070 fruPdr->entity_instance == entity.entity_instance_num &&
1071 fruPdr->container_id == entity.entity_container_id)
George Liu682ee182020-12-25 15:24:33 +08001072 {
1073 return fruPdr->fru_rsi;
1074 }
1075 }
1076
1077 return std::nullopt;
1078}
1079
1080void HostPDRHandler::setFRUDataOnDBus(
Patrick Williamsd310f822023-10-07 19:01:19 -05001081 [[maybe_unused]] const PDRList& fruRecordSetPDRs,
1082 [[maybe_unused]] const std::vector<
1083 responder::pdr_utils::FruRecordDataFormat>& fruRecordData)
George Liu682ee182020-12-25 15:24:33 +08001084{
Patrick Williamsd310f822023-10-07 19:01:19 -05001085#ifdef OEM_IBM
George Liu682ee182020-12-25 15:24:33 +08001086 for (const auto& entity : objPathMap)
1087 {
1088 pldm_entity node = pldm_entity_extract(entity.second);
1089 auto fruRSI = getRSI(fruRecordSetPDRs, node);
1090
1091 for (const auto& data : fruRecordData)
1092 {
1093 if (!fruRSI || *fruRSI != data.fruRSI)
1094 {
1095 continue;
1096 }
1097
1098 if (data.fruRecType == PLDM_FRU_RECORD_TYPE_OEM)
1099 {
1100 for (const auto& tlv : data.fruTLV)
1101 {
1102 if (tlv.fruFieldType ==
1103 PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE)
1104 {
1105 CustomDBus::getCustomDBus().setLocationCode(
1106 entity.first,
1107 std::string(reinterpret_cast<const char*>(
1108 tlv.fruFieldValue.data()),
1109 tlv.fruFieldLen));
1110 }
1111 }
1112 }
1113 }
1114 }
Patrick Williamsd310f822023-10-07 19:01:19 -05001115#endif
George Liu682ee182020-12-25 15:24:33 +08001116}
1117void HostPDRHandler::createDbusObjects(const PDRList& fruRecordSetPDRs)
1118{
1119 // TODO: Creating and Refreshing dbus hosted by remote PLDM entity Fru PDRs
1120
1121 getFRURecordTableMetadataByRemote(fruRecordSetPDRs);
1122}
1123
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001124} // namespace pldm