blob: 13d83a16c6b5b0e9328031e1fbf77125428ee25a [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;
Kamalkumar Patel516122e2024-05-07 04:39:32 -050029using namespace pldm::hostbmc::utils;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050030using Json = nlohmann::json;
31namespace fs = std::filesystem;
George Liu682ee182020-12-25 15:24:33 +080032using namespace pldm::dbus;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050033constexpr auto fruJson = "host_frus.json";
34const Json emptyJson{};
35const std::vector<Json> emptyJsonList{};
36
Manojkiran Eda3ca40452021-10-04 22:51:37 +053037template <typename T>
38uint16_t extractTerminusHandle(std::vector<uint8_t>& pdr)
39{
40 T* var = nullptr;
41 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
42 {
43 var = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
44 }
45 else
46 {
47 var = (T*)(pdr.data());
48 }
49 if (var != nullptr)
50 {
51 return var->terminus_handle;
52 }
53 return TERMINUS_HANDLE;
54}
55
George Liu96af8cb2021-07-31 15:23:45 +080056template <typename T>
57void updateContainerId(pldm_entity_association_tree* entityTree,
58 std::vector<uint8_t>& pdr)
59{
60 T* t = nullptr;
61 if (entityTree == nullptr)
62 {
63 return;
64 }
65 if (std::is_same<T, pldm_pdr_fru_record_set>::value)
66 {
67 t = (T*)(pdr.data() + sizeof(pldm_pdr_hdr));
68 }
69 else
70 {
71 t = (T*)(pdr.data());
72 }
73 if (t == nullptr)
74 {
75 return;
76 }
77
78 pldm_entity entity{t->entity_type, t->entity_instance, t->container_id};
79 auto node = pldm_entity_association_tree_find_with_locality(entityTree,
80 &entity, true);
81 if (node)
82 {
83 pldm_entity e = pldm_entity_extract(node);
84 t->container_id = e.entity_container_id;
85 }
86}
87
Tom Joseph74f27c72021-05-16 07:58:53 -070088HostPDRHandler::HostPDRHandler(
89 int mctp_fd, uint8_t mctp_eid, sdeventplus::Event& event, pldm_pdr* repo,
90 const std::string& eventsJsonsDir, pldm_entity_association_tree* entityTree,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093091 pldm_entity_association_tree* bmcEntityTree,
92 pldm::InstanceIdDb& instanceIdDb,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050093 pldm::requester::Handler<pldm::requester::Request>* handler,
94 pldm::responder::oem_platform::Handler* oemPlatformHandler) :
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050095 mctp_fd(mctp_fd),
Pavithra Barithaya3aec9972020-12-14 01:55:44 -060096 mctp_eid(mctp_eid), event(event), repo(repo),
97 stateSensorHandler(eventsJsonsDir), entityTree(entityTree),
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050098 bmcEntityTree(bmcEntityTree), instanceIdDb(instanceIdDb), handler(handler),
Kamalkumar Patel516122e2024-05-07 04:39:32 -050099 oemPlatformHandler(oemPlatformHandler),
100 entityMaps(parseEntityMap(ENTITY_MAP_JSON))
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500101{
George Liuacf2c8c2021-05-10 14:08:52 +0800102 mergedHostParents = false;
Patrick Williams84b790c2022-07-22 19:26:56 -0500103 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500104 pldm::utils::DBusHandler::getBus(),
105 propertiesChanged("/xyz/openbmc_project/state/host0",
106 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -0500107 [this, repo, entityTree, bmcEntityTree](sdbusplus::message_t& msg) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500108 DbusChangedProps props{};
109 std::string intf;
110 msg.read(intf, props);
111 const auto itr = props.find("CurrentHostState");
112 if (itr != props.end())
113 {
114 PropertyValue value = itr->second;
115 auto propVal = std::get<std::string>(value);
116 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500117 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500118 // Delete all the remote terminus information
119 std::erase_if(tlPDRInfo, [](const auto& item) {
120 auto const& [key, value] = item;
121 return key != TERMINUS_HANDLE;
122 });
123 pldm_pdr_remove_remote_pdrs(repo);
124 pldm_entity_association_tree_destroy_root(entityTree);
125 pldm_entity_association_tree_copy_root(bmcEntityTree,
126 entityTree);
127 this->sensorMap.clear();
128 this->responseReceived = false;
George Liuacf2c8c2021-05-10 14:08:52 +0800129 this->mergedHostParents = false;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500130 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500131 }
Patrick Williamsa6756622023-10-20 11:19:15 -0500132 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500133}
134
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500135void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500136{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500137 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500138 modifiedPDRRecordHandles.clear();
139
140 if (isHostPdrModified)
141 {
142 modifiedPDRRecordHandles = std::move(recordHandles);
143 }
144 else
145 {
146 pdrRecordHandles = std::move(recordHandles);
147 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500148
149 // Defer the actual fetch of PDRs from the host (by queuing the call on the
150 // main event loop). That way, we can respond to the platform event msg from
151 // the host firmware.
152 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
153 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
154 std::placeholders::_1));
155}
156
157void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
158{
Sampa Misrac0c79482021-06-02 08:01:54 -0500159 getHostPDR();
160}
161
162void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
163{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500164 pdrFetchEvent.reset();
165
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500166 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
167 PLDM_GET_PDR_REQ_BYTES);
168 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500169 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500170 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
171 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500172 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500173 recordHandle = modifiedPDRRecordHandles.front();
174 modifiedPDRRecordHandles.pop_front();
175 }
176 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
177 {
178 recordHandle = pdrRecordHandles.front();
179 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500180 }
181 else
182 {
183 recordHandle = nextRecordHandle;
184 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930185 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500186
Patrick Williams6da4f912023-05-10 07:50:53 -0500187 auto rc = encode_get_pdr_req(instanceId, recordHandle, 0,
188 PLDM_GET_FIRSTPART, UINT16_MAX, 0, request,
189 PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500190 if (rc != PLDM_SUCCESS)
191 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930192 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500193 error("Failed to encode get pdr request, response code '{RC}'", "RC",
194 rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500195 return;
196 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500197
Sampa Misrac0c79482021-06-02 08:01:54 -0500198 rc = handler->registerRequest(
199 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
200 std::move(requestMsg),
201 std::move(std::bind_front(&HostPDRHandler::processHostPDRs, this)));
202 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500203 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500204 error(
205 "Failed to send the getPDR request to remote terminus, response code '{RC}'",
206 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500207 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500208}
209
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600210int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
211 pdr::EventState state)
212{
213 auto rc = stateSensorHandler.eventAction(entry, state);
214 if (rc != PLDM_SUCCESS)
215 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500216 error("Failed to fetch and update D-bus property, response code '{RC}'",
217 "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600218 return rc;
219 }
220 return PLDM_SUCCESS;
221}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500222
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500223void HostPDRHandler::mergeEntityAssociations(
224 const std::vector<uint8_t>& pdr, [[maybe_unused]] const uint32_t& size,
225 [[maybe_unused]] const uint32_t& record_handle)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500226{
227 size_t numEntities{};
228 pldm_entity* entities = nullptr;
229 bool merged = false;
230 auto entityPdr = reinterpret_cast<pldm_pdr_entity_association*>(
231 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
232
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500233 if (oemPlatformHandler &&
234 oemPlatformHandler->checkRecordHandleInRange(record_handle))
235 {
236 // Adding the remote range PDRs to the repo before merging it
237 uint32_t handle = record_handle;
238 pldm_pdr_add_check(repo, pdr.data(), size, true, 0xFFFF, &handle);
239 }
240
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500241 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
242 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800243 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500244 {
George Liuacf2c8c2021-05-10 14:08:52 +0800245 pldm_entity_node* pNode = nullptr;
246 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500247 {
George Liuacf2c8c2021-05-10 14:08:52 +0800248 pNode = pldm_entity_association_tree_find_with_locality(
249 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500250 }
George Liuacf2c8c2021-05-10 14:08:52 +0800251 else
252 {
253 pNode = pldm_entity_association_tree_find_with_locality(
254 entityTree, &entities[0], true);
255 }
256 if (!pNode)
257 {
258 return;
259 }
260
George Liudf9a6d32020-12-22 16:27:16 +0800261 Entities entityAssoc;
262 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800263 for (size_t i = 1; i < numEntities; ++i)
264 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500265 bool isUpdateContainerId = true;
266 if (oemPlatformHandler)
267 {
268 isUpdateContainerId =
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600269 checkIfLogicalBitSet(entities[i].entity_container_id);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500270 }
George Liudf9a6d32020-12-22 16:27:16 +0800271 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800272 entityTree, &entities[i], entities[i].entity_instance_num,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500273 pNode, entityPdr->association_type, true, isUpdateContainerId,
274 0xFFFF);
275 if (!node)
276 {
277 continue;
278 }
George Liuacf2c8c2021-05-10 14:08:52 +0800279 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800280 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800281 }
282
283 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800284 if (merged)
285 {
286 entityAssociations.push_back(entityAssoc);
287 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500288 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500289
290 if (merged)
291 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500292 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500293 pldm_entity_node* node = nullptr;
294 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
295 if (node == nullptr)
296 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500297 error("Failed to find referrence of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500298 }
299 else
300 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500301 int rc = 0;
302 if (oemPlatformHandler)
303 {
304 auto record = oemPlatformHandler->fetchLastBMCRecord(repo);
305
306 uint32_t record_handle = pldm_pdr_get_record_handle(repo,
307 record);
308
309 rc =
310 pldm_entity_association_pdr_add_from_node_with_record_handle(
311 node, repo, &entities, numEntities, true,
312 TERMINUS_HANDLE, (record_handle + 1));
313 }
314 else
315 {
316 rc = pldm_entity_association_pdr_add_from_node_check(
317 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
318 }
319
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930320 if (rc)
321 {
322 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500323 "Failed to add entity association PDR from node, response code '{RC}'",
324 "RC", rc);
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930325 }
Sampa Misra719ed392021-06-04 05:15:13 -0500326 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500327 }
Sampa Misra719ed392021-06-04 05:15:13 -0500328 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500329}
330
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500331void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
332 uint8_t eventDataFormat)
333{
334 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
335
336 // Extract from the PDR repo record handles of PDRs we want the host
337 // to pull up.
338 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
339 std::vector<uint8_t> numsOfChangeEntries(1);
340 std::vector<std::vector<ChangeEntry>> changeEntries(
341 numsOfChangeEntries.size());
342 for (auto pdrType : pdrTypes)
343 {
344 const pldm_pdr_record* record{};
345 do
346 {
347 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
348 nullptr, nullptr);
349 if (record && pldm_pdr_record_is_remote(record))
350 {
351 changeEntries[0].push_back(
352 pldm_pdr_get_record_handle(repo, record));
353 }
354 } while (record);
355 }
356 if (changeEntries.empty())
357 {
358 return;
359 }
360 numsOfChangeEntries[0] = changeEntries[0].size();
361
362 // Encode PLDM platform event msg to indicate a PDR repo change.
363 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
364 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
365 changeEntries[0].size() * sizeof(uint32_t);
366 std::vector<uint8_t> eventDataVec{};
367 eventDataVec.resize(maxSize);
368 auto eventData =
369 reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
370 eventDataVec.data());
371 size_t actualSize{};
372 auto firstEntry = changeEntries[0].data();
373 auto rc = encode_pldm_pdr_repository_chg_event_data(
374 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
375 &firstEntry, eventData, &actualSize, maxSize);
376 if (rc != PLDM_SUCCESS)
377 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500378 error(
379 "Failed to encode pldm pdr repository change event data, response code '{RC}'",
380 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500381 return;
382 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930383 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500384 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
385 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
386 actualSize);
387 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
388 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600389 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
390 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500391 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500392 if (rc != PLDM_SUCCESS)
393 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930394 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500395 error(
396 "Failed to encode platform event message request, response code '{RC}'",
397 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500398 return;
399 }
400
Patrick Williams6da4f912023-05-10 07:50:53 -0500401 auto platformEventMessageResponseHandler =
402 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700403 if (response == nullptr || !respMsgLen)
404 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600405 error(
406 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700407 return;
408 }
409
410 uint8_t completionCode{};
411 uint8_t status{};
412 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500413 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
414 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500415 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700416 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600417 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500418 "Failed to decode platform event message response, response code '{RC}' and completion code '{CC}'",
419 "RC", rc, "CC", completionCode);
Tom Joseph74f27c72021-05-16 07:58:53 -0700420 }
421 };
422
Sampa Misrac0c79482021-06-02 08:01:54 -0500423 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500424 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700425 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500426 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500427 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500428 error(
429 "Failed to send the PDR repository changed event request, response code '{RC}'",
430 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500431 }
432}
433
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530434void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500435{
436 for (const auto& pdr : stateSensorPDRs)
437 {
438 SensorEntry sensorEntry{};
439 const auto& [terminusHandle, sensorID, sensorInfo] =
440 responder::pdr_utils::parseStateSensorPDR(pdr);
441 sensorEntry.sensorID = sensorID;
442 try
443 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530444 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500445 }
446 // If there is no mapping for terminusHandle assign the reserved TID
447 // value of 0xFF to indicate that.
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500448 catch (const std::out_of_range&)
Sampa Misra868c8792020-05-26 03:12:13 -0500449 {
450 sensorEntry.terminusID = PLDM_TID_RESERVED;
451 }
452 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
453 }
454}
455
Sampa Misrac0c79482021-06-02 08:01:54 -0500456void HostPDRHandler::processHostPDRs(mctp_eid_t /*eid*/,
457 const pldm_msg* response,
458 size_t respMsgLen)
459{
460 static bool merged = false;
461 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800462 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500463 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600464 uint8_t tlEid = 0;
465 bool tlValid = true;
466 uint32_t rh = 0;
467 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530468 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600469 uint8_t tid = 0;
470
Sampa Misrac0c79482021-06-02 08:01:54 -0500471 uint8_t completionCode{};
472 uint32_t nextDataTransferHandle{};
473 uint8_t transferFlag{};
474 uint16_t respCount{};
475 uint8_t transferCRC{};
476 if (response == nullptr || !respMsgLen)
477 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600478 error("Failed to receive response for the GetPDR command");
Sampa Misrac0c79482021-06-02 08:01:54 -0500479 return;
480 }
481
482 auto rc = decode_get_pdr_resp(
483 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
484 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
485 nullptr, 0, &transferCRC);
486 std::vector<uint8_t> responsePDRMsg;
487 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
488 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500489 if (rc != PLDM_SUCCESS)
490 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500491 error(
492 "Failed to decode getPDR response for next record handle '{NEXT_RECORD_HANDLE}', response code '{RC}'",
493 "NEXT_RECORD_HANDLE", nextRecordHandle, "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500494 return;
495 }
496 else
497 {
498 std::vector<uint8_t> pdr(respCount, 0);
499 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
500 &nextRecordHandle, &nextDataTransferHandle,
501 &transferFlag, &respCount, pdr.data(),
502 respCount, &transferCRC);
503 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
504 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500505 error(
506 "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}'",
507 "NEXT_RECORD_HANDLE", nextRecordHandle, "DATA_TRANSFER_HANDLE",
508 nextDataTransferHandle, "FLAG", transferFlag, "RC", rc, "CC",
509 completionCode);
Sampa Misrac0c79482021-06-02 08:01:54 -0500510 return;
511 }
512 else
513 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600514 // when nextRecordHandle is 0, we need the recordHandle of the last
515 // PDR and not 0-1.
516 if (!nextRecordHandle)
517 {
518 rh = nextRecordHandle;
519 }
520 else
521 {
522 rh = nextRecordHandle - 1;
523 }
524
Sampa Misrac0c79482021-06-02 08:01:54 -0500525 auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600526 if (!rh)
527 {
528 rh = pdrHdr->record_handle;
529 }
530
Sampa Misrac0c79482021-06-02 08:01:54 -0500531 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
532 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500533 this->mergeEntityAssociations(pdr, respCount, rh);
Sampa Misrac0c79482021-06-02 08:01:54 -0500534 merged = true;
535 }
536 else
537 {
538 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
539 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530540 pdrTerminusHandle =
541 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500542 auto tlpdr =
543 reinterpret_cast<const pldm_terminus_locator_pdr*>(
544 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600545
546 terminusHandle = tlpdr->terminus_handle;
547 tid = tlpdr->tid;
548 auto terminus_locator_type = tlpdr->terminus_locator_type;
549 if (terminus_locator_type ==
550 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
551 {
552 auto locatorValue = reinterpret_cast<
553 const pldm_terminus_locator_type_mctp_eid*>(
554 tlpdr->terminus_locator_value);
555 tlEid = static_cast<uint8_t>(locatorValue->eid);
556 }
557 if (tlpdr->validity == 0)
558 {
559 tlValid = false;
560 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500561 for (const auto& terminusMap : tlPDRInfo)
562 {
563 if ((terminusHandle == (terminusMap.first)) &&
564 (get<1>(terminusMap.second) == tlEid) &&
565 (get<2>(terminusMap.second) == tlpdr->validity))
566 {
567 // TL PDR already present with same validity don't
568 // add the PDR to the repo just return
569 return;
570 }
571 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530572 tlPDRInfo.insert_or_assign(
573 tlpdr->terminus_handle,
574 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500575 }
576 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
577 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530578 pdrTerminusHandle =
579 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800580 updateContainerId<pldm_state_sensor_pdr>(entityTree, pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500581 stateSensorPDRs.emplace_back(pdr);
582 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530583 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
584 {
585 pdrTerminusHandle =
586 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800587 updateContainerId<pldm_pdr_fru_record_set>(entityTree, pdr);
George Liu682ee182020-12-25 15:24:33 +0800588 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530589 }
590 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
591 {
592 pdrTerminusHandle =
593 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800594 updateContainerId<pldm_state_effecter_pdr>(entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530595 }
596 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
597 {
598 pdrTerminusHandle =
599 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
600 pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800601 updateContainerId<pldm_numeric_effecter_value_pdr>(
602 entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530603 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600604 // if the TLPDR is invalid update the repo accordingly
605 if (!tlValid)
606 {
607 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
608 tlValid);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500609
610 if (!isHostUp())
611 {
612 // The terminus PDR becomes invalid when the terminus
613 // itself is down. We don't need to do PDR exchange in
614 // that case, so setting the next record handle to 0.
615 nextRecordHandle = 0;
616 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600617 }
618 else
619 {
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930620 rc = pldm_pdr_add_check(repo, pdr.data(), respCount, true,
621 pdrTerminusHandle, &rh);
622 if (rc)
623 {
624 // pldm_pdr_add() assert()ed on failure to add a PDR.
625 throw std::runtime_error("Failed to add PDR");
626 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600627 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500628 }
629 }
630 }
631 if (!nextRecordHandle)
632 {
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500633 updateEntityAssociation(entityAssociations, entityTree, objPathMap,
634 entityMaps);
George Liudf9a6d32020-12-22 16:27:16 +0800635
Sampa Misrac0c79482021-06-02 08:01:54 -0500636 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530637 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800638 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600639 if (isHostUp())
640 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530641 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600642 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500643 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800644 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800645 entityAssociations.clear();
646
Sampa Misrac0c79482021-06-02 08:01:54 -0500647 if (merged)
648 {
649 merged = false;
650 deferredPDRRepoChgEvent =
651 std::make_unique<sdeventplus::source::Defer>(
652 event,
653 std::bind(
654 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
655 this, std::placeholders::_1));
656 }
657 }
658 else
659 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500660 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
661 {
662 isHostPdrModified = false;
663 }
664 else
665 {
666 deferredFetchPDREvent =
667 std::make_unique<sdeventplus::source::Defer>(
668 event,
669 std::bind(
670 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
671 this, nextRecordHandle, std::placeholders::_1));
672 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500673 }
674}
675
676void HostPDRHandler::_processPDRRepoChgEvent(
677 sdeventplus::source::EventBase& /*source */)
678{
679 deferredPDRRepoChgEvent.reset();
680 this->sendPDRRepositoryChgEvent(
681 std::move(std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION)),
682 FORMAT_IS_PDR_HANDLES);
683}
684
685void HostPDRHandler::_processFetchPDREvent(
686 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
687{
688 deferredFetchPDREvent.reset();
689 if (!this->pdrRecordHandles.empty())
690 {
691 nextRecordHandle = this->pdrRecordHandles.front();
692 this->pdrRecordHandles.pop_front();
693 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500694 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
695 {
696 nextRecordHandle = this->modifiedPDRRecordHandles.front();
697 this->modifiedPDRRecordHandles.pop_front();
698 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500699 this->getHostPDR(nextRecordHandle);
700}
701
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500702void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530703{
sampmisr6decfc12021-03-02 11:07:36 +0530704 responseReceived = false;
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930705 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500706 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
707 PLDM_GET_VERSION_REQ_BYTES);
708 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
709 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
710 PLDM_BASE, request);
711 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530712 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500713 error("Failed to encode GetPLDMVersion, response code {RC}", "RC",
Riya Dixit49cfb132023-03-02 04:26:53 -0600714 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930715 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530716 return;
717 }
718
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500719 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
720 const pldm_msg* response,
721 size_t respMsgLen) {
722 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530723 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600724 error(
725 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530726 return;
727 }
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500728 info("Getting the response code '{RC}'", "RC", lg2::hex,
Riya Dixit49cfb132023-03-02 04:26:53 -0600729 static_cast<uint16_t>(response->payload[0]));
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500730 this->responseReceived = true;
731 getHostPDR();
sampmisr6decfc12021-03-02 11:07:36 +0530732 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500733 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
734 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
735 std::move(getPLDMVersionHandler));
736 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530737 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500738 error(
739 "Failed to discover remote terminus state. Assuming remote terminus as off");
sampmisr6decfc12021-03-02 11:07:36 +0530740 }
741}
742
743bool HostPDRHandler::isHostUp()
744{
745 return responseReceived;
746}
747
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530748void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600749{
750 for (const auto& stateSensorPDR : stateSensorPDRs)
751 {
752 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
753 stateSensorPDR.data());
754
755 if (!pdr)
756 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500757 error("Failed to get state sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600758 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530759 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600760 return;
761 }
762
763 uint16_t sensorId = pdr->sensor_id;
764
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530765 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600766 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530767 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600768 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530769 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600770 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530771 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600772 }
773
774 bitfield8_t sensorRearm;
775 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530776 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600777
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930778 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600779 std::vector<uint8_t> requestMsg(
780 sizeof(pldm_msg_hdr) +
781 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
782 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
783 auto rc = encode_get_state_sensor_readings_req(
784 instanceId, sensorId, sensorRearm, 0, request);
785
786 if (rc != PLDM_SUCCESS)
787 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930788 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600789 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500790 "Failed to encode get state sensor readings request for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
791 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
792 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600793 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530794 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600795 return;
796 }
797
Patrick Williams6da4f912023-05-10 07:50:53 -0500798 auto getStateSensorReadingRespHandler =
799 [=, this](mctp_eid_t /*eid*/, const pldm_msg* response,
800 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600801 if (response == nullptr || !respMsgLen)
802 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600803 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500804 "Failed to receive response for get state sensor reading command for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}'",
805 "SENSOR_ID", sensorId, "INSTANCE", instanceId);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600806 return;
807 }
808 std::array<get_sensor_state_field, 8> stateField{};
809 uint8_t completionCode = 0;
810 uint8_t comp_sensor_count = 0;
811
812 auto rc = decode_get_state_sensor_readings_resp(
813 response, respMsgLen, &completionCode,
814 &comp_sensor_count, stateField.data());
815
816 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
817 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600818 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500819 "Failed to decode get state sensor readings response for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code'{RC}' and completion code '{CC}'",
820 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
821 rc, "CC", completionCode);
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530822 pldm::utils::reportError(
823 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600824 }
825
826 uint8_t eventState;
827 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600828
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500829 for (uint8_t sensorOffset = 0;
830 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600831 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500832 eventState = stateField[sensorOffset].present_state;
833 previousEventState =
834 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600835
836 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
837 eventState,
838 previousEventState);
839
840 SensorEntry sensorEntry{tid, sensorId};
841
842 pldm::pdr::EntityInfo entityInfo{};
843 pldm::pdr::CompositeSensorStates
844 compositeSensorStates{};
Sagar Srinivase3607a32024-02-16 03:50:53 -0600845 std::vector<pldm::pdr::StateSetId> stateSetIds{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600846
847 try
848 {
Sagar Srinivase3607a32024-02-16 03:50:53 -0600849 std::tie(entityInfo, compositeSensorStates,
850 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600851 lookupSensorInfo(sensorEntry);
852 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500853 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600854 {
855 try
856 {
857 sensorEntry.terminusID = PLDM_TID_RESERVED;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600858 std::tie(entityInfo, compositeSensorStates,
859 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600860 lookupSensorInfo(sensorEntry);
861 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500862 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600863 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600864 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600865 }
866 }
867
Manojkiran Eda07a07e22024-04-24 19:15:10 +0530868 if ((compositeSensorStates.size() > 1) &&
869 (sensorOffset > (compositeSensorStates.size() - 1)))
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600870 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500871 error(
872 "Error Invalid data, Invalid sensor offset '{SENSOR_OFFSET}'",
873 "SENSOR_OFFSET", sensorOffset);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600874 return;
875 }
876
877 const auto& possibleStates =
878 compositeSensorStates[sensorOffset];
879 if (possibleStates.find(eventState) ==
880 possibleStates.end())
881 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500882 error(
883 "Error invalid_data, Invalid event state '{STATE}'",
884 "STATE", eventState);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600885 return;
886 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500887 const auto& [containerId, entityType,
888 entityInstance] = entityInfo;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600889 auto stateSetId = stateSetIds[sensorOffset];
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600890 pldm::responder::events::StateSensorEntry
891 stateSensorEntry{containerId, entityType,
Sagar Srinivase3607a32024-02-16 03:50:53 -0600892 entityInstance, sensorOffset,
893 stateSetId};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600894 handleStateSensorEvent(stateSensorEntry, eventState);
895 }
896 };
897
898 rc = handler->registerRequest(
899 mctp_eid, instanceId, PLDM_PLATFORM,
900 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg),
901 std::move(getStateSensorReadingRespHandler));
902
903 if (rc != PLDM_SUCCESS)
904 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600905 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500906 "Failed to send request to get state sensor reading on remote terminus for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
907 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
908 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600909 }
910 }
911 }
912 }
913}
George Liu682ee182020-12-25 15:24:33 +0800914
915void HostPDRHandler::getFRURecordTableMetadataByRemote(
916 const PDRList& fruRecordSetPDRs)
917{
918 auto instanceId = instanceIdDb.next(mctp_eid);
919 std::vector<uint8_t> requestMsg(
920 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
921
922 // GetFruRecordTableMetadata
923 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
924 auto rc = encode_get_fru_record_table_metadata_req(
925 instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
926 if (rc != PLDM_SUCCESS)
927 {
928 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500929 error(
930 "Failed to encode get fru record table metadata request, response code '{RC}'",
George Liu682ee182020-12-25 15:24:33 +0800931 "RC", lg2::hex, rc);
932 return;
933 }
934
935 auto getFruRecordTableMetadataResponseHandler =
936 [this, fruRecordSetPDRs](mctp_eid_t /*eid*/, const pldm_msg* response,
937 size_t respMsgLen) {
938 if (response == nullptr || !respMsgLen)
939 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500940 error(
941 "Failed to receive response for the get fru record table metadata");
George Liu682ee182020-12-25 15:24:33 +0800942 return;
943 }
944
945 uint8_t cc = 0;
946 uint8_t fru_data_major_version, fru_data_minor_version;
947 uint32_t fru_table_maximum_size, fru_table_length;
948 uint16_t total_record_set_identifiers;
949 uint16_t total;
950 uint32_t checksum;
951
952 auto rc = decode_get_fru_record_table_metadata_resp(
953 response, respMsgLen, &cc, &fru_data_major_version,
954 &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
955 &total_record_set_identifiers, &total, &checksum);
956
957 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
958 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500959 error(
960 "Failed to decode get fru record table metadata response, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +0800961 "RC", lg2::hex, rc, "CC", cc);
962 return;
963 }
964
965 // pass total to getFRURecordTableByRemote
966 this->getFRURecordTableByRemote(fruRecordSetPDRs, total);
967 };
968
969 rc = handler->registerRequest(
970 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA,
971 std::move(requestMsg),
972 std::move(getFruRecordTableMetadataResponseHandler));
973 if (rc != PLDM_SUCCESS)
974 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500975 error(
976 "Failed to send the the set state effecter states request, response code '{RC}'",
977 "RC", rc);
George Liu682ee182020-12-25 15:24:33 +0800978 }
979
980 return;
981}
982
983void HostPDRHandler::getFRURecordTableByRemote(const PDRList& fruRecordSetPDRs,
984 uint16_t totalTableRecords)
985{
986 fruRecordData.clear();
987
988 if (!totalTableRecords)
989 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500990 error("Failed to get fru record table");
George Liu682ee182020-12-25 15:24:33 +0800991 return;
992 }
993
994 auto instanceId = instanceIdDb.next(mctp_eid);
995 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
996 PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
997
998 // send the getFruRecordTable command
999 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
1000 auto rc = encode_get_fru_record_table_req(
1001 instanceId, 0, PLDM_GET_FIRSTPART, request,
1002 requestMsg.size() - sizeof(pldm_msg_hdr));
1003 if (rc != PLDM_SUCCESS)
1004 {
1005 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001006 error(
1007 "Failed to encode get fru record table request, response code '{RC}'",
1008 "RC", lg2::hex, rc);
George Liu682ee182020-12-25 15:24:33 +08001009 return;
1010 }
1011
1012 auto getFruRecordTableResponseHandler =
1013 [totalTableRecords, this, fruRecordSetPDRs](
1014 mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
1015 if (response == nullptr || !respMsgLen)
1016 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001017 error("Failed to receive response for the get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001018 return;
1019 }
1020
1021 uint8_t cc = 0;
1022 uint32_t next_data_transfer_handle = 0;
1023 uint8_t transfer_flag = 0;
1024 size_t fru_record_table_length = 0;
1025 std::vector<uint8_t> fru_record_table_data(respMsgLen -
1026 sizeof(pldm_msg_hdr));
1027 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
1028 auto rc = decode_get_fru_record_table_resp(
Manojkiran Eda33a9cd02024-01-22 11:06:59 +05301029 responsePtr, respMsgLen, &cc, &next_data_transfer_handle,
1030 &transfer_flag, fru_record_table_data.data(),
1031 &fru_record_table_length);
George Liu682ee182020-12-25 15:24:33 +08001032
1033 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
1034 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001035 error(
1036 "Failed to decode get fru record table resp, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +08001037 "RC", lg2::hex, rc, "CC", cc);
1038 return;
1039 }
1040
1041 fruRecordData = responder::pdr_utils::parseFruRecordTable(
1042 fru_record_table_data.data(), fru_record_table_length);
1043
1044 if (totalTableRecords != fruRecordData.size())
1045 {
1046 fruRecordData.clear();
1047
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001048 error("Failed to parse fru recrod data format.");
George Liu682ee182020-12-25 15:24:33 +08001049 return;
1050 }
1051
1052 this->setFRUDataOnDBus(fruRecordSetPDRs, fruRecordData);
1053 };
1054
1055 rc = handler->registerRequest(
1056 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE,
1057 std::move(requestMsg), std::move(getFruRecordTableResponseHandler));
1058 if (rc != PLDM_SUCCESS)
1059 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001060 error("Failed to send the the set state effecter states request");
George Liu682ee182020-12-25 15:24:33 +08001061 }
1062}
1063
1064std::optional<uint16_t> HostPDRHandler::getRSI(const PDRList& fruRecordSetPDRs,
1065 const pldm_entity& entity)
1066{
1067 for (const auto& pdr : fruRecordSetPDRs)
1068 {
1069 auto fruPdr = reinterpret_cast<const pldm_pdr_fru_record_set*>(
1070 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
1071
1072 if (fruPdr->entity_type == entity.entity_type &&
Sagar Srinivasebf8bb52023-10-06 01:15:55 -05001073 fruPdr->entity_instance == entity.entity_instance_num &&
1074 fruPdr->container_id == entity.entity_container_id)
George Liu682ee182020-12-25 15:24:33 +08001075 {
1076 return fruPdr->fru_rsi;
1077 }
1078 }
1079
1080 return std::nullopt;
1081}
1082
1083void HostPDRHandler::setFRUDataOnDBus(
Patrick Williamsd310f822023-10-07 19:01:19 -05001084 [[maybe_unused]] const PDRList& fruRecordSetPDRs,
1085 [[maybe_unused]] const std::vector<
1086 responder::pdr_utils::FruRecordDataFormat>& fruRecordData)
George Liu682ee182020-12-25 15:24:33 +08001087{
Patrick Williamsd310f822023-10-07 19:01:19 -05001088#ifdef OEM_IBM
George Liu682ee182020-12-25 15:24:33 +08001089 for (const auto& entity : objPathMap)
1090 {
1091 pldm_entity node = pldm_entity_extract(entity.second);
1092 auto fruRSI = getRSI(fruRecordSetPDRs, node);
1093
1094 for (const auto& data : fruRecordData)
1095 {
1096 if (!fruRSI || *fruRSI != data.fruRSI)
1097 {
1098 continue;
1099 }
1100
1101 if (data.fruRecType == PLDM_FRU_RECORD_TYPE_OEM)
1102 {
1103 for (const auto& tlv : data.fruTLV)
1104 {
1105 if (tlv.fruFieldType ==
1106 PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE)
1107 {
1108 CustomDBus::getCustomDBus().setLocationCode(
1109 entity.first,
1110 std::string(reinterpret_cast<const char*>(
1111 tlv.fruFieldValue.data()),
1112 tlv.fruFieldLen));
1113 }
1114 }
1115 }
1116 }
1117 }
Patrick Williamsd310f822023-10-07 19:01:19 -05001118#endif
George Liu682ee182020-12-25 15:24:33 +08001119}
1120void HostPDRHandler::createDbusObjects(const PDRList& fruRecordSetPDRs)
1121{
1122 // TODO: Creating and Refreshing dbus hosted by remote PLDM entity Fru PDRs
1123
1124 getFRURecordTableMetadataByRemote(fruRecordSetPDRs);
1125}
1126
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001127} // namespace pldm