blob: 38d3be965b5683335b3c552b140cf9ce1271aead [file] [log] [blame]
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001#include "host_pdr_handler.hpp"
2
Andrew Jeffery4668f5c2024-01-15 14:59:17 +10303#include <libpldm/fru.h>
George Liu682ee182020-12-25 15:24:33 +08004#ifdef OEM_IBM
Andrew Jeffery21f128d2024-01-15 15:34:26 +10305#include <libpldm/oem/ibm/fru.h>
Sagar Srinivas3687e2b2023-04-10 05:08:28 -05006#endif
Kamalkumar Patel14107a12024-06-19 08:50:01 -05007#include "dbus/custom_dbus.hpp"
George Liu682ee182020-12-25 15:24:33 +08008
Pavithra Barithayae8beb892020-04-14 23:24:25 -05009#include <assert.h>
10
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050011#include <nlohmann/json.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060012#include <phosphor-logging/lg2.hpp>
sampmisr6decfc12021-03-02 11:07:36 +053013#include <sdeventplus/clock.hpp>
14#include <sdeventplus/exception.hpp>
15#include <sdeventplus/source/io.hpp>
16#include <sdeventplus/source/time.hpp>
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050017
George Liu6492f522020-06-16 10:34:05 +080018#include <fstream>
George Liu96af8cb2021-07-31 15:23:45 +080019#include <type_traits>
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050020
Riya Dixit49cfb132023-03-02 04:26:53 -060021PHOSPHOR_LOG2_USING;
22
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050023namespace pldm
24{
Brad Bishop5079ac42021-08-19 18:35:06 -040025using namespace pldm::responder::events;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -050026using namespace pldm::utils;
27using namespace sdbusplus::bus::match::rules;
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050028using namespace pldm::responder::pdr_utils;
Kamalkumar Patel516122e2024-05-07 04:39:32 -050029using namespace pldm::hostbmc::utils;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050030using Json = nlohmann::json;
31namespace fs = std::filesystem;
George Liu682ee182020-12-25 15:24:33 +080032using namespace pldm::dbus;
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050033constexpr auto fruJson = "host_frus.json";
34const Json emptyJson{};
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050035
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,
George Liua881c172021-06-21 18:28:11 +080092 pldm::requester::Handler<pldm::requester::Request>* handler) :
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050093 mctp_fd(mctp_fd),
Pavithra Barithaya3aec9972020-12-14 01:55:44 -060094 mctp_eid(mctp_eid), event(event), repo(repo),
95 stateSensorHandler(eventsJsonsDir), entityTree(entityTree),
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050096 bmcEntityTree(bmcEntityTree), instanceIdDb(instanceIdDb), handler(handler),
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -050097 entityMaps(parseEntityMap(ENTITY_MAP_JSON)), oemUtilsHandler(nullptr)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -050098{
George Liuacf2c8c2021-05-10 14:08:52 +080099 mergedHostParents = false;
Patrick Williams84b790c2022-07-22 19:26:56 -0500100 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500101 pldm::utils::DBusHandler::getBus(),
102 propertiesChanged("/xyz/openbmc_project/state/host0",
103 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -0500104 [this, repo, entityTree, bmcEntityTree](sdbusplus::message_t& msg) {
Patrick Williams6da4f912023-05-10 07:50:53 -0500105 DbusChangedProps props{};
106 std::string intf;
107 msg.read(intf, props);
108 const auto itr = props.find("CurrentHostState");
109 if (itr != props.end())
110 {
111 PropertyValue value = itr->second;
112 auto propVal = std::get<std::string>(value);
113 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500114 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500115 // Delete all the remote terminus information
116 std::erase_if(tlPDRInfo, [](const auto& item) {
117 auto const& [key, value] = item;
118 return key != TERMINUS_HANDLE;
119 });
120 pldm_pdr_remove_remote_pdrs(repo);
121 pldm_entity_association_tree_destroy_root(entityTree);
122 pldm_entity_association_tree_copy_root(bmcEntityTree,
123 entityTree);
124 this->sensorMap.clear();
125 this->responseReceived = false;
George Liuacf2c8c2021-05-10 14:08:52 +0800126 this->mergedHostParents = false;
Deepak Kodihalli6b1d1ca2020-04-27 07:24:51 -0500127 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500128 }
Patrick Williamsa6756622023-10-20 11:19:15 -0500129 });
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500130}
131
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500132void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500133{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500134 pdrRecordHandles.clear();
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500135 modifiedPDRRecordHandles.clear();
136
137 if (isHostPdrModified)
138 {
139 modifiedPDRRecordHandles = std::move(recordHandles);
140 }
141 else
142 {
143 pdrRecordHandles = std::move(recordHandles);
144 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500145
146 // Defer the actual fetch of PDRs from the host (by queuing the call on the
147 // main event loop). That way, we can respond to the platform event msg from
148 // the host firmware.
149 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
150 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
151 std::placeholders::_1));
152}
153
154void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
155{
Sampa Misrac0c79482021-06-02 08:01:54 -0500156 getHostPDR();
157}
158
159void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
160{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500161 pdrFetchEvent.reset();
162
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500163 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
164 PLDM_GET_PDR_REQ_BYTES);
165 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500166 uint32_t recordHandle{};
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500167 if (!nextRecordHandle && (!modifiedPDRRecordHandles.empty()) &&
168 isHostPdrModified)
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500169 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500170 recordHandle = modifiedPDRRecordHandles.front();
171 modifiedPDRRecordHandles.pop_front();
172 }
173 else if (!nextRecordHandle && (!pdrRecordHandles.empty()))
174 {
175 recordHandle = pdrRecordHandles.front();
176 pdrRecordHandles.pop_front();
Sampa Misrac0c79482021-06-02 08:01:54 -0500177 }
178 else
179 {
180 recordHandle = nextRecordHandle;
181 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930182 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misrac0c79482021-06-02 08:01:54 -0500183
Patrick Williams6da4f912023-05-10 07:50:53 -0500184 auto rc = encode_get_pdr_req(instanceId, recordHandle, 0,
185 PLDM_GET_FIRSTPART, UINT16_MAX, 0, request,
186 PLDM_GET_PDR_REQ_BYTES);
Sampa Misrac0c79482021-06-02 08:01:54 -0500187 if (rc != PLDM_SUCCESS)
188 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930189 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500190 error("Failed to encode get pdr request, response code '{RC}'", "RC",
191 rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500192 return;
193 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500194
Sampa Misrac0c79482021-06-02 08:01:54 -0500195 rc = handler->registerRequest(
196 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
197 std::move(requestMsg),
198 std::move(std::bind_front(&HostPDRHandler::processHostPDRs, this)));
199 if (rc)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500200 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500201 error(
202 "Failed to send the getPDR request to remote terminus, response code '{RC}'",
203 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500204 }
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500205}
206
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600207int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry,
208 pdr::EventState state)
209{
210 auto rc = stateSensorHandler.eventAction(entry, state);
211 if (rc != PLDM_SUCCESS)
212 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500213 error("Failed to fetch and update D-bus property, response code '{RC}'",
214 "RC", rc);
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600215 return rc;
216 }
217 return PLDM_SUCCESS;
218}
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500219
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500220void HostPDRHandler::mergeEntityAssociations(
221 const std::vector<uint8_t>& pdr, [[maybe_unused]] const uint32_t& size,
222 [[maybe_unused]] const uint32_t& record_handle)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500223{
224 size_t numEntities{};
225 pldm_entity* entities = nullptr;
226 bool merged = false;
227 auto entityPdr = reinterpret_cast<pldm_pdr_entity_association*>(
228 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
229
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500230 if (oemPlatformHandler &&
231 oemPlatformHandler->checkRecordHandleInRange(record_handle))
232 {
233 // Adding the remote range PDRs to the repo before merging it
234 uint32_t handle = record_handle;
235 pldm_pdr_add_check(repo, pdr.data(), size, true, 0xFFFF, &handle);
236 }
237
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500238 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities,
239 &entities);
George Liuacf2c8c2021-05-10 14:08:52 +0800240 if (numEntities > 0)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500241 {
George Liuacf2c8c2021-05-10 14:08:52 +0800242 pldm_entity_node* pNode = nullptr;
243 if (!mergedHostParents)
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500244 {
George Liuacf2c8c2021-05-10 14:08:52 +0800245 pNode = pldm_entity_association_tree_find_with_locality(
246 entityTree, &entities[0], false);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500247 }
George Liuacf2c8c2021-05-10 14:08:52 +0800248 else
249 {
250 pNode = pldm_entity_association_tree_find_with_locality(
251 entityTree, &entities[0], true);
252 }
253 if (!pNode)
254 {
255 return;
256 }
257
George Liudf9a6d32020-12-22 16:27:16 +0800258 Entities entityAssoc;
259 entityAssoc.push_back(pNode);
George Liuacf2c8c2021-05-10 14:08:52 +0800260 for (size_t i = 1; i < numEntities; ++i)
261 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500262 bool isUpdateContainerId = true;
263 if (oemPlatformHandler)
264 {
265 isUpdateContainerId =
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600266 checkIfLogicalBitSet(entities[i].entity_container_id);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500267 }
George Liudf9a6d32020-12-22 16:27:16 +0800268 auto node = pldm_entity_association_tree_add_entity(
George Liuacf2c8c2021-05-10 14:08:52 +0800269 entityTree, &entities[i], entities[i].entity_instance_num,
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500270 pNode, entityPdr->association_type, true, isUpdateContainerId,
271 0xFFFF);
272 if (!node)
273 {
274 continue;
275 }
George Liuacf2c8c2021-05-10 14:08:52 +0800276 merged = true;
George Liudf9a6d32020-12-22 16:27:16 +0800277 entityAssoc.push_back(node);
George Liuacf2c8c2021-05-10 14:08:52 +0800278 }
279
280 mergedHostParents = true;
George Liudf9a6d32020-12-22 16:27:16 +0800281 if (merged)
282 {
283 entityAssociations.push_back(entityAssoc);
284 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500285 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500286
287 if (merged)
288 {
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500289 // Update our PDR repo with the merged entity association PDRs
Sampa Misra719ed392021-06-04 05:15:13 -0500290 pldm_entity_node* node = nullptr;
291 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node);
292 if (node == nullptr)
293 {
Manojkiran Eda2576aec2024-06-17 12:05:17 +0530294 error("Failed to find reference of the entity in the tree");
Sampa Misra719ed392021-06-04 05:15:13 -0500295 }
296 else
297 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500298 int rc = 0;
299 if (oemPlatformHandler)
300 {
301 auto record = oemPlatformHandler->fetchLastBMCRecord(repo);
302
303 uint32_t record_handle = pldm_pdr_get_record_handle(repo,
304 record);
305
306 rc =
307 pldm_entity_association_pdr_add_from_node_with_record_handle(
308 node, repo, &entities, numEntities, true,
309 TERMINUS_HANDLE, (record_handle + 1));
310 }
311 else
312 {
313 rc = pldm_entity_association_pdr_add_from_node_check(
314 node, repo, &entities, numEntities, true, TERMINUS_HANDLE);
315 }
316
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930317 if (rc)
318 {
319 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500320 "Failed to add entity association PDR from node, response code '{RC}'",
321 "RC", rc);
Andrew Jeffery1fd3c512023-07-03 13:02:03 +0930322 }
Sampa Misra719ed392021-06-04 05:15:13 -0500323 }
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500324 }
Sampa Misra719ed392021-06-04 05:15:13 -0500325 free(entities);
Deepak Kodihalli87514cc2020-04-16 09:08:38 -0500326}
327
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500328void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes,
329 uint8_t eventDataFormat)
330{
331 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES);
332
333 // Extract from the PDR repo record handles of PDRs we want the host
334 // to pull up.
335 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED};
336 std::vector<uint8_t> numsOfChangeEntries(1);
337 std::vector<std::vector<ChangeEntry>> changeEntries(
338 numsOfChangeEntries.size());
339 for (auto pdrType : pdrTypes)
340 {
341 const pldm_pdr_record* record{};
342 do
343 {
344 record = pldm_pdr_find_record_by_type(repo, pdrType, record,
345 nullptr, nullptr);
346 if (record && pldm_pdr_record_is_remote(record))
347 {
348 changeEntries[0].push_back(
349 pldm_pdr_get_record_handle(repo, record));
350 }
351 } while (record);
352 }
353 if (changeEntries.empty())
354 {
355 return;
356 }
357 numsOfChangeEntries[0] = changeEntries[0].size();
358
359 // Encode PLDM platform event msg to indicate a PDR repo change.
360 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
361 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
362 changeEntries[0].size() * sizeof(uint32_t);
363 std::vector<uint8_t> eventDataVec{};
364 eventDataVec.resize(maxSize);
365 auto eventData =
366 reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
367 eventDataVec.data());
368 size_t actualSize{};
369 auto firstEntry = changeEntries[0].data();
370 auto rc = encode_pldm_pdr_repository_chg_event_data(
371 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
372 &firstEntry, eventData, &actualSize, maxSize);
373 if (rc != PLDM_SUCCESS)
374 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500375 error(
376 "Failed to encode pldm pdr repository change event data, response code '{RC}'",
377 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500378 return;
379 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930380 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500381 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
382 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
383 actualSize);
384 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
385 rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600386 instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
387 eventDataVec.data(), actualSize, request,
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500388 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500389 if (rc != PLDM_SUCCESS)
390 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930391 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500392 error(
393 "Failed to encode platform event message request, response code '{RC}'",
394 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500395 return;
396 }
397
Patrick Williams6da4f912023-05-10 07:50:53 -0500398 auto platformEventMessageResponseHandler =
399 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
Tom Joseph74f27c72021-05-16 07:58:53 -0700400 if (response == nullptr || !respMsgLen)
401 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600402 error(
403 "Failed to receive response for the PDR repository changed event");
Tom Joseph74f27c72021-05-16 07:58:53 -0700404 return;
405 }
406
407 uint8_t completionCode{};
408 uint8_t status{};
409 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
Pavithra Barithaya54b5a562021-09-27 06:07:10 -0500410 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
411 &completionCode, &status);
Sampa Misrac0c79482021-06-02 08:01:54 -0500412 if (rc || completionCode)
Tom Joseph74f27c72021-05-16 07:58:53 -0700413 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600414 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500415 "Failed to decode platform event message response, response code '{RC}' and completion code '{CC}'",
416 "RC", rc, "CC", completionCode);
Tom Joseph74f27c72021-05-16 07:58:53 -0700417 }
418 };
419
Sampa Misrac0c79482021-06-02 08:01:54 -0500420 rc = handler->registerRequest(
Sampa Misra626c5652021-08-11 10:28:48 -0500421 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
Tom Joseph74f27c72021-05-16 07:58:53 -0700422 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
Sampa Misrac0c79482021-06-02 08:01:54 -0500423 if (rc)
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500424 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500425 error(
426 "Failed to send the PDR repository changed event request, response code '{RC}'",
427 "RC", rc);
Pavithra Barithayae8beb892020-04-14 23:24:25 -0500428 }
429}
430
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530431void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs)
Sampa Misra868c8792020-05-26 03:12:13 -0500432{
433 for (const auto& pdr : stateSensorPDRs)
434 {
435 SensorEntry sensorEntry{};
436 const auto& [terminusHandle, sensorID, sensorInfo] =
437 responder::pdr_utils::parseStateSensorPDR(pdr);
438 sensorEntry.sensorID = sensorID;
439 try
440 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530441 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle));
Sampa Misra868c8792020-05-26 03:12:13 -0500442 }
443 // If there is no mapping for terminusHandle assign the reserved TID
444 // value of 0xFF to indicate that.
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500445 catch (const std::out_of_range&)
Sampa Misra868c8792020-05-26 03:12:13 -0500446 {
447 sensorEntry.terminusID = PLDM_TID_RESERVED;
448 }
449 sensorMap.emplace(sensorEntry, std::move(sensorInfo));
450 }
451}
452
Sampa Misrac0c79482021-06-02 08:01:54 -0500453void HostPDRHandler::processHostPDRs(mctp_eid_t /*eid*/,
454 const pldm_msg* response,
455 size_t respMsgLen)
456{
457 static bool merged = false;
458 static PDRList stateSensorPDRs{};
George Liu682ee182020-12-25 15:24:33 +0800459 static PDRList fruRecordSetPDRs{};
Sampa Misrac0c79482021-06-02 08:01:54 -0500460 uint32_t nextRecordHandle{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600461 uint8_t tlEid = 0;
462 bool tlValid = true;
463 uint32_t rh = 0;
464 uint16_t terminusHandle = 0;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530465 uint16_t pdrTerminusHandle = 0;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600466 uint8_t tid = 0;
467
Sampa Misrac0c79482021-06-02 08:01:54 -0500468 uint8_t completionCode{};
469 uint32_t nextDataTransferHandle{};
470 uint8_t transferFlag{};
471 uint16_t respCount{};
472 uint8_t transferCRC{};
473 if (response == nullptr || !respMsgLen)
474 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600475 error("Failed to receive response for the GetPDR command");
Riya Dixit478e71d2024-06-21 14:10:14 -0500476 pldm::utils::reportError(
477 "xyz.openbmc_project.PLDM.Error.GetPDR.PDRExchangeFailure");
Sampa Misrac0c79482021-06-02 08:01:54 -0500478 return;
479 }
480
481 auto rc = decode_get_pdr_resp(
482 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
483 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
484 nullptr, 0, &transferCRC);
485 std::vector<uint8_t> responsePDRMsg;
486 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
487 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
Sampa Misrac0c79482021-06-02 08:01:54 -0500488 if (rc != PLDM_SUCCESS)
489 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500490 error(
491 "Failed to decode getPDR response for next record handle '{NEXT_RECORD_HANDLE}', response code '{RC}'",
492 "NEXT_RECORD_HANDLE", nextRecordHandle, "RC", rc);
Sampa Misrac0c79482021-06-02 08:01:54 -0500493 return;
494 }
495 else
496 {
497 std::vector<uint8_t> pdr(respCount, 0);
498 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
499 &nextRecordHandle, &nextDataTransferHandle,
500 &transferFlag, &respCount, pdr.data(),
501 respCount, &transferCRC);
502 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
503 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500504 error(
505 "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}'",
506 "NEXT_RECORD_HANDLE", nextRecordHandle, "DATA_TRANSFER_HANDLE",
507 nextDataTransferHandle, "FLAG", transferFlag, "RC", rc, "CC",
508 completionCode);
Sampa Misrac0c79482021-06-02 08:01:54 -0500509 return;
510 }
511 else
512 {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600513 // when nextRecordHandle is 0, we need the recordHandle of the last
514 // PDR and not 0-1.
515 if (!nextRecordHandle)
516 {
517 rh = nextRecordHandle;
518 }
519 else
520 {
521 rh = nextRecordHandle - 1;
522 }
523
Sampa Misrac0c79482021-06-02 08:01:54 -0500524 auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600525 if (!rh)
526 {
527 rh = pdrHdr->record_handle;
528 }
529
Sampa Misrac0c79482021-06-02 08:01:54 -0500530 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
531 {
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500532 this->mergeEntityAssociations(pdr, respCount, rh);
Sampa Misrac0c79482021-06-02 08:01:54 -0500533 merged = true;
534 }
535 else
536 {
537 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
538 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530539 pdrTerminusHandle =
540 extractTerminusHandle<pldm_terminus_locator_pdr>(pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500541 auto tlpdr =
542 reinterpret_cast<const pldm_terminus_locator_pdr*>(
543 pdr.data());
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600544
545 terminusHandle = tlpdr->terminus_handle;
546 tid = tlpdr->tid;
547 auto terminus_locator_type = tlpdr->terminus_locator_type;
548 if (terminus_locator_type ==
549 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
550 {
551 auto locatorValue = reinterpret_cast<
552 const pldm_terminus_locator_type_mctp_eid*>(
553 tlpdr->terminus_locator_value);
554 tlEid = static_cast<uint8_t>(locatorValue->eid);
555 }
556 if (tlpdr->validity == 0)
557 {
558 tlValid = false;
559 }
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500560 for (const auto& terminusMap : tlPDRInfo)
561 {
562 if ((terminusHandle == (terminusMap.first)) &&
563 (get<1>(terminusMap.second) == tlEid) &&
564 (get<2>(terminusMap.second) == tlpdr->validity))
565 {
566 // TL PDR already present with same validity don't
567 // add the PDR to the repo just return
568 return;
569 }
570 }
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530571 tlPDRInfo.insert_or_assign(
572 tlpdr->terminus_handle,
573 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
Sampa Misrac0c79482021-06-02 08:01:54 -0500574 }
575 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
576 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530577 pdrTerminusHandle =
578 extractTerminusHandle<pldm_state_sensor_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800579 updateContainerId<pldm_state_sensor_pdr>(entityTree, pdr);
Sampa Misrac0c79482021-06-02 08:01:54 -0500580 stateSensorPDRs.emplace_back(pdr);
581 }
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530582 else if (pdrHdr->type == PLDM_PDR_FRU_RECORD_SET)
583 {
584 pdrTerminusHandle =
585 extractTerminusHandle<pldm_pdr_fru_record_set>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800586 updateContainerId<pldm_pdr_fru_record_set>(entityTree, pdr);
George Liu682ee182020-12-25 15:24:33 +0800587 fruRecordSetPDRs.emplace_back(pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530588 }
589 else if (pdrHdr->type == PLDM_STATE_EFFECTER_PDR)
590 {
591 pdrTerminusHandle =
592 extractTerminusHandle<pldm_state_effecter_pdr>(pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800593 updateContainerId<pldm_state_effecter_pdr>(entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530594 }
595 else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
596 {
597 pdrTerminusHandle =
598 extractTerminusHandle<pldm_numeric_effecter_value_pdr>(
599 pdr);
George Liu96af8cb2021-07-31 15:23:45 +0800600 updateContainerId<pldm_numeric_effecter_value_pdr>(
601 entityTree, pdr);
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530602 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600603 // if the TLPDR is invalid update the repo accordingly
604 if (!tlValid)
605 {
606 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid,
607 tlValid);
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500608
609 if (!isHostUp())
610 {
611 // The terminus PDR becomes invalid when the terminus
612 // itself is down. We don't need to do PDR exchange in
613 // that case, so setting the next record handle to 0.
614 nextRecordHandle = 0;
615 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600616 }
617 else
618 {
Andrew Jeffery64f37fe2023-07-03 15:41:13 +0930619 rc = pldm_pdr_add_check(repo, pdr.data(), respCount, true,
620 pdrTerminusHandle, &rh);
621 if (rc)
622 {
623 // pldm_pdr_add() assert()ed on failure to add a PDR.
624 throw std::runtime_error("Failed to add PDR");
625 }
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600626 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500627 }
628 }
629 }
630 if (!nextRecordHandle)
631 {
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500632 updateEntityAssociation(entityAssociations, entityTree, objPathMap,
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500633 entityMaps, oemPlatformHandler);
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -0500634 if (oemUtilsHandler)
635 {
636 oemUtilsHandler->setCoreCount(entityAssociations, entityMaps);
637 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500638 /*received last record*/
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530639 this->parseStateSensorPDRs(stateSensorPDRs);
George Liu682ee182020-12-25 15:24:33 +0800640 this->createDbusObjects(fruRecordSetPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600641 if (isHostUp())
642 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530643 this->setHostSensorState(stateSensorPDRs);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600644 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500645 stateSensorPDRs.clear();
George Liu682ee182020-12-25 15:24:33 +0800646 fruRecordSetPDRs.clear();
George Liudf9a6d32020-12-22 16:27:16 +0800647 entityAssociations.clear();
648
Sampa Misrac0c79482021-06-02 08:01:54 -0500649 if (merged)
650 {
651 merged = false;
652 deferredPDRRepoChgEvent =
653 std::make_unique<sdeventplus::source::Defer>(
654 event,
655 std::bind(
656 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
657 this, std::placeholders::_1));
658 }
659 }
660 else
661 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500662 if (modifiedPDRRecordHandles.empty() && isHostPdrModified)
663 {
664 isHostPdrModified = false;
665 }
666 else
667 {
668 deferredFetchPDREvent =
669 std::make_unique<sdeventplus::source::Defer>(
670 event,
671 std::bind(
672 std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
673 this, nextRecordHandle, std::placeholders::_1));
674 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500675 }
676}
677
678void HostPDRHandler::_processPDRRepoChgEvent(
679 sdeventplus::source::EventBase& /*source */)
680{
681 deferredPDRRepoChgEvent.reset();
682 this->sendPDRRepositoryChgEvent(
683 std::move(std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION)),
684 FORMAT_IS_PDR_HANDLES);
685}
686
687void HostPDRHandler::_processFetchPDREvent(
688 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
689{
690 deferredFetchPDREvent.reset();
691 if (!this->pdrRecordHandles.empty())
692 {
693 nextRecordHandle = this->pdrRecordHandles.front();
694 this->pdrRecordHandles.pop_front();
695 }
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500696 if (isHostPdrModified && (!this->modifiedPDRRecordHandles.empty()))
697 {
698 nextRecordHandle = this->modifiedPDRRecordHandles.front();
699 this->modifiedPDRRecordHandles.pop_front();
700 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500701 this->getHostPDR(nextRecordHandle);
702}
703
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500704void HostPDRHandler::setHostFirmwareCondition()
sampmisr6decfc12021-03-02 11:07:36 +0530705{
sampmisr6decfc12021-03-02 11:07:36 +0530706 responseReceived = false;
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930707 auto instanceId = instanceIdDb.next(mctp_eid);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500708 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
709 PLDM_GET_VERSION_REQ_BYTES);
710 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
711 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
712 PLDM_BASE, request);
713 if (rc != PLDM_SUCCESS)
sampmisr6decfc12021-03-02 11:07:36 +0530714 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500715 error("Failed to encode GetPLDMVersion, response code {RC}", "RC",
Riya Dixit49cfb132023-03-02 04:26:53 -0600716 lg2::hex, rc);
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930717 instanceIdDb.free(mctp_eid, instanceId);
sampmisr6decfc12021-03-02 11:07:36 +0530718 return;
719 }
720
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500721 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/,
722 const pldm_msg* response,
723 size_t respMsgLen) {
724 if (response == nullptr || !respMsgLen)
sampmisr6decfc12021-03-02 11:07:36 +0530725 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600726 error(
727 "Failed to receive response for getPLDMVersion command, Host seems to be off");
sampmisr6decfc12021-03-02 11:07:36 +0530728 return;
729 }
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500730 info("Getting the response code '{RC}'", "RC", lg2::hex,
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500731 response->payload[0]);
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500732 this->responseReceived = true;
sampmisr6decfc12021-03-02 11:07:36 +0530733 };
Sampa Misraf9ba8c12021-08-06 00:33:47 -0500734 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE,
735 PLDM_GET_PLDM_VERSION, std::move(requestMsg),
736 std::move(getPLDMVersionHandler));
737 if (rc)
sampmisr6decfc12021-03-02 11:07:36 +0530738 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500739 error(
740 "Failed to discover remote terminus state. Assuming remote terminus as off");
sampmisr6decfc12021-03-02 11:07:36 +0530741 }
742}
743
744bool HostPDRHandler::isHostUp()
745{
746 return responseReceived;
747}
748
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530749void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600750{
751 for (const auto& stateSensorPDR : stateSensorPDRs)
752 {
753 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(
754 stateSensorPDR.data());
755
756 if (!pdr)
757 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500758 error("Failed to get state sensor PDR");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600759 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530760 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600761 return;
762 }
763
764 uint16_t sensorId = pdr->sensor_id;
765
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530766 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600767 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530768 if (terminusHandle == pdr->terminus_handle)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600769 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530770 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600771 {
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530772 mctp_eid = std::get<1>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600773 }
774
775 bitfield8_t sensorRearm;
776 sensorRearm.byte = 0;
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530777 uint8_t tid = std::get<0>(terminusInfo);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600778
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930779 auto instanceId = instanceIdDb.next(mctp_eid);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600780 std::vector<uint8_t> requestMsg(
781 sizeof(pldm_msg_hdr) +
782 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES);
783 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
784 auto rc = encode_get_state_sensor_readings_req(
785 instanceId, sensorId, sensorRearm, 0, request);
786
787 if (rc != PLDM_SUCCESS)
788 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930789 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600790 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500791 "Failed to encode get state sensor readings request for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
792 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
793 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600794 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530795 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600796 return;
797 }
798
Patrick Williams6da4f912023-05-10 07:50:53 -0500799 auto getStateSensorReadingRespHandler =
800 [=, this](mctp_eid_t /*eid*/, const pldm_msg* response,
801 size_t respMsgLen) {
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600802 if (response == nullptr || !respMsgLen)
803 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600804 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500805 "Failed to receive response for get state sensor reading command for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}'",
806 "SENSOR_ID", sensorId, "INSTANCE", instanceId);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600807 return;
808 }
809 std::array<get_sensor_state_field, 8> stateField{};
810 uint8_t completionCode = 0;
811 uint8_t comp_sensor_count = 0;
812
813 auto rc = decode_get_state_sensor_readings_resp(
814 response, respMsgLen, &completionCode,
815 &comp_sensor_count, stateField.data());
816
817 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
818 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600819 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500820 "Failed to decode get state sensor readings response for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code'{RC}' and completion code '{CC}'",
821 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
822 rc, "CC", completionCode);
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530823 pldm::utils::reportError(
824 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600825 }
826
827 uint8_t eventState;
828 uint8_t previousEventState;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600829
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500830 for (uint8_t sensorOffset = 0;
831 sensorOffset < comp_sensor_count; sensorOffset++)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600832 {
RIYA DIXITbb5fda42022-09-27 06:48:08 -0500833 eventState = stateField[sensorOffset].present_state;
834 previousEventState =
835 stateField[sensorOffset].previous_state;
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600836
837 emitStateSensorEventSignal(tid, sensorId, sensorOffset,
838 eventState,
839 previousEventState);
840
841 SensorEntry sensorEntry{tid, sensorId};
842
843 pldm::pdr::EntityInfo entityInfo{};
844 pldm::pdr::CompositeSensorStates
845 compositeSensorStates{};
Sagar Srinivase3607a32024-02-16 03:50:53 -0600846 std::vector<pldm::pdr::StateSetId> stateSetIds{};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600847
848 try
849 {
Sagar Srinivase3607a32024-02-16 03:50:53 -0600850 std::tie(entityInfo, compositeSensorStates,
851 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600852 lookupSensorInfo(sensorEntry);
853 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500854 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600855 {
856 try
857 {
858 sensorEntry.terminusID = PLDM_TID_RESERVED;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600859 std::tie(entityInfo, compositeSensorStates,
860 stateSetIds) =
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600861 lookupSensorInfo(sensorEntry);
862 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500863 catch (const std::out_of_range&)
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600864 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600865 error("No mapping for the events");
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600866 }
867 }
868
Manojkiran Eda07a07e22024-04-24 19:15:10 +0530869 if ((compositeSensorStates.size() > 1) &&
870 (sensorOffset > (compositeSensorStates.size() - 1)))
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600871 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500872 error(
873 "Error Invalid data, Invalid sensor offset '{SENSOR_OFFSET}'",
874 "SENSOR_OFFSET", sensorOffset);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600875 return;
876 }
877
878 const auto& possibleStates =
879 compositeSensorStates[sensorOffset];
880 if (possibleStates.find(eventState) ==
881 possibleStates.end())
882 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500883 error(
884 "Error invalid_data, Invalid event state '{STATE}'",
885 "STATE", eventState);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600886 return;
887 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500888 const auto& [containerId, entityType,
889 entityInstance] = entityInfo;
Sagar Srinivase3607a32024-02-16 03:50:53 -0600890 auto stateSetId = stateSetIds[sensorOffset];
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600891 pldm::responder::events::StateSensorEntry
Manojkiran Edafa084702024-05-27 10:20:30 +0530892 stateSensorEntry{containerId, entityType,
Sagar Srinivase3607a32024-02-16 03:50:53 -0600893 entityInstance, sensorOffset,
Manojkiran Edafa084702024-05-27 10:20:30 +0530894 stateSetId, false};
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600895 handleStateSensorEvent(stateSensorEntry, eventState);
896 }
897 };
898
899 rc = handler->registerRequest(
900 mctp_eid, instanceId, PLDM_PLATFORM,
901 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg),
902 std::move(getStateSensorReadingRespHandler));
903
904 if (rc != PLDM_SUCCESS)
905 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600906 error(
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500907 "Failed to send request to get state sensor reading on remote terminus for sensorID '{SENSOR_ID}' and instanceID '{INSTANCE}', response code '{RC}'",
908 "SENSOR_ID", sensorId, "INSTANCE", instanceId, "RC",
909 rc);
Pavithra Barithaya4f2538a2021-03-05 07:32:15 -0600910 }
911 }
912 }
913 }
914}
George Liu682ee182020-12-25 15:24:33 +0800915
916void HostPDRHandler::getFRURecordTableMetadataByRemote(
917 const PDRList& fruRecordSetPDRs)
918{
919 auto instanceId = instanceIdDb.next(mctp_eid);
920 std::vector<uint8_t> requestMsg(
921 sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
922
923 // GetFruRecordTableMetadata
924 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
925 auto rc = encode_get_fru_record_table_metadata_req(
926 instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
927 if (rc != PLDM_SUCCESS)
928 {
929 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500930 error(
931 "Failed to encode get fru record table metadata request, response code '{RC}'",
George Liu682ee182020-12-25 15:24:33 +0800932 "RC", lg2::hex, rc);
933 return;
934 }
935
936 auto getFruRecordTableMetadataResponseHandler =
937 [this, fruRecordSetPDRs](mctp_eid_t /*eid*/, const pldm_msg* response,
938 size_t respMsgLen) {
939 if (response == nullptr || !respMsgLen)
940 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500941 error(
942 "Failed to receive response for the get fru record table metadata");
George Liu682ee182020-12-25 15:24:33 +0800943 return;
944 }
945
946 uint8_t cc = 0;
947 uint8_t fru_data_major_version, fru_data_minor_version;
948 uint32_t fru_table_maximum_size, fru_table_length;
949 uint16_t total_record_set_identifiers;
950 uint16_t total;
951 uint32_t checksum;
952
953 auto rc = decode_get_fru_record_table_metadata_resp(
954 response, respMsgLen, &cc, &fru_data_major_version,
955 &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
956 &total_record_set_identifiers, &total, &checksum);
957
958 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
959 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500960 error(
961 "Failed to decode get fru record table metadata response, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +0800962 "RC", lg2::hex, rc, "CC", cc);
963 return;
964 }
965
966 // pass total to getFRURecordTableByRemote
967 this->getFRURecordTableByRemote(fruRecordSetPDRs, total);
968 };
969
970 rc = handler->registerRequest(
971 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA,
972 std::move(requestMsg),
973 std::move(getFruRecordTableMetadataResponseHandler));
974 if (rc != PLDM_SUCCESS)
975 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500976 error(
977 "Failed to send the the set state effecter states request, response code '{RC}'",
978 "RC", rc);
George Liu682ee182020-12-25 15:24:33 +0800979 }
980
981 return;
982}
983
984void HostPDRHandler::getFRURecordTableByRemote(const PDRList& fruRecordSetPDRs,
985 uint16_t totalTableRecords)
986{
987 fruRecordData.clear();
988
989 if (!totalTableRecords)
990 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -0500991 error("Failed to get fru record table");
George Liu682ee182020-12-25 15:24:33 +0800992 return;
993 }
994
995 auto instanceId = instanceIdDb.next(mctp_eid);
996 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
997 PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
998
999 // send the getFruRecordTable command
1000 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
1001 auto rc = encode_get_fru_record_table_req(
1002 instanceId, 0, PLDM_GET_FIRSTPART, request,
1003 requestMsg.size() - sizeof(pldm_msg_hdr));
1004 if (rc != PLDM_SUCCESS)
1005 {
1006 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001007 error(
1008 "Failed to encode get fru record table request, response code '{RC}'",
1009 "RC", lg2::hex, rc);
George Liu682ee182020-12-25 15:24:33 +08001010 return;
1011 }
1012
1013 auto getFruRecordTableResponseHandler =
1014 [totalTableRecords, this, fruRecordSetPDRs](
1015 mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
1016 if (response == nullptr || !respMsgLen)
1017 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001018 error("Failed to receive response for the get fru record table");
George Liu682ee182020-12-25 15:24:33 +08001019 return;
1020 }
1021
1022 uint8_t cc = 0;
1023 uint32_t next_data_transfer_handle = 0;
1024 uint8_t transfer_flag = 0;
1025 size_t fru_record_table_length = 0;
1026 std::vector<uint8_t> fru_record_table_data(respMsgLen -
1027 sizeof(pldm_msg_hdr));
1028 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
1029 auto rc = decode_get_fru_record_table_resp(
Manojkiran Eda33a9cd02024-01-22 11:06:59 +05301030 responsePtr, respMsgLen, &cc, &next_data_transfer_handle,
1031 &transfer_flag, fru_record_table_data.data(),
1032 &fru_record_table_length);
George Liu682ee182020-12-25 15:24:33 +08001033
1034 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
1035 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001036 error(
1037 "Failed to decode get fru record table resp, response code '{RC}' and completion code '{CC}'",
George Liu682ee182020-12-25 15:24:33 +08001038 "RC", lg2::hex, rc, "CC", cc);
1039 return;
1040 }
1041
1042 fruRecordData = responder::pdr_utils::parseFruRecordTable(
1043 fru_record_table_data.data(), fru_record_table_length);
1044
1045 if (totalTableRecords != fruRecordData.size())
1046 {
1047 fruRecordData.clear();
1048
Manojkiran Eda2576aec2024-06-17 12:05:17 +05301049 error("Failed to parse fru record data format.");
George Liu682ee182020-12-25 15:24:33 +08001050 return;
1051 }
1052
1053 this->setFRUDataOnDBus(fruRecordSetPDRs, fruRecordData);
1054 };
1055
1056 rc = handler->registerRequest(
1057 mctp_eid, instanceId, PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE,
1058 std::move(requestMsg), std::move(getFruRecordTableResponseHandler));
1059 if (rc != PLDM_SUCCESS)
1060 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -05001061 error("Failed to send the the set state effecter states request");
George Liu682ee182020-12-25 15:24:33 +08001062 }
1063}
1064
1065std::optional<uint16_t> HostPDRHandler::getRSI(const PDRList& fruRecordSetPDRs,
1066 const pldm_entity& entity)
1067{
1068 for (const auto& pdr : fruRecordSetPDRs)
1069 {
1070 auto fruPdr = reinterpret_cast<const pldm_pdr_fru_record_set*>(
1071 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
1072
1073 if (fruPdr->entity_type == entity.entity_type &&
Sagar Srinivasebf8bb52023-10-06 01:15:55 -05001074 fruPdr->entity_instance == entity.entity_instance_num &&
1075 fruPdr->container_id == entity.entity_container_id)
George Liu682ee182020-12-25 15:24:33 +08001076 {
1077 return fruPdr->fru_rsi;
1078 }
1079 }
1080
1081 return std::nullopt;
1082}
1083
1084void HostPDRHandler::setFRUDataOnDBus(
Patrick Williamsd310f822023-10-07 19:01:19 -05001085 [[maybe_unused]] const PDRList& fruRecordSetPDRs,
1086 [[maybe_unused]] const std::vector<
1087 responder::pdr_utils::FruRecordDataFormat>& fruRecordData)
George Liu682ee182020-12-25 15:24:33 +08001088{
Patrick Williamsd310f822023-10-07 19:01:19 -05001089#ifdef OEM_IBM
George Liu682ee182020-12-25 15:24:33 +08001090 for (const auto& entity : objPathMap)
1091 {
1092 pldm_entity node = pldm_entity_extract(entity.second);
1093 auto fruRSI = getRSI(fruRecordSetPDRs, node);
1094
1095 for (const auto& data : fruRecordData)
1096 {
1097 if (!fruRSI || *fruRSI != data.fruRSI)
1098 {
1099 continue;
1100 }
1101
1102 if (data.fruRecType == PLDM_FRU_RECORD_TYPE_OEM)
1103 {
1104 for (const auto& tlv : data.fruTLV)
1105 {
1106 if (tlv.fruFieldType ==
1107 PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE)
1108 {
1109 CustomDBus::getCustomDBus().setLocationCode(
1110 entity.first,
1111 std::string(reinterpret_cast<const char*>(
1112 tlv.fruFieldValue.data()),
1113 tlv.fruFieldLen));
1114 }
1115 }
1116 }
1117 }
1118 }
Patrick Williamsd310f822023-10-07 19:01:19 -05001119#endif
George Liu682ee182020-12-25 15:24:33 +08001120}
1121void HostPDRHandler::createDbusObjects(const PDRList& fruRecordSetPDRs)
1122{
1123 // TODO: Creating and Refreshing dbus hosted by remote PLDM entity Fru PDRs
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001124 for (const auto& entity : objPathMap)
1125 {
1126 pldm_entity node = pldm_entity_extract(entity.second);
1127 switch (node.entity_type)
1128 {
1129 case PLDM_ENTITY_PROC | 0x8000:
1130 CustomDBus::getCustomDBus().implementCpuCoreInterface(
1131 entity.first);
1132 break;
Archana Kakanibf1fd272024-06-05 13:25:53 -05001133 case PLDM_ENTITY_SLOT:
1134 CustomDBus::getCustomDBus().implementPCIeSlotInterface(
1135 entity.first);
1136 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001137 case PLDM_ENTITY_CARD:
1138 CustomDBus::getCustomDBus().implementPCIeDeviceInterface(
1139 entity.first);
1140 break;
Kamalkumar Patel2ed986c2024-05-08 02:20:47 -05001141 case PLDM_ENTITY_SYS_BOARD:
1142 CustomDBus::getCustomDBus().implementMotherboardInterface(
1143 entity.first);
1144 break;
Archana Kakani733b39d2024-06-05 21:05:20 -05001145 default:
1146 break;
Kamalkumar Patel56da5742024-05-23 04:53:07 -05001147 }
1148 }
George Liu682ee182020-12-25 15:24:33 +08001149 getFRURecordTableMetadataByRemote(fruRecordSetPDRs);
1150}
1151
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001152} // namespace pldm