blob: e2cbd50ca21d90dd6adc05ae2c39c1f891f2d053 [file] [log] [blame]
George Liu83409572019-12-24 18:42:54 +08001#include "utils.hpp"
2
George Liuc453e162022-12-21 17:16:23 +08003#include <libpldm/pdr.h>
4#include <libpldm/pldm_types.h>
Gilbert Chen6c7fed42022-02-22 15:40:17 +00005#include <linux/mctp.h>
George Liu6492f522020-06-16 10:34:05 +08006
7#include <xyz/openbmc_project/Common/error.hpp>
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -06008#include <xyz/openbmc_project/Logging/Create/client.hpp>
9#include <xyz/openbmc_project/ObjectMapper/client.hpp>
George Liu6492f522020-06-16 10:34:05 +080010
Tom Joseph54922072021-06-19 02:45:46 -070011#include <algorithm>
George Liu83409572019-12-24 18:42:54 +080012#include <array>
Tom Joseph54922072021-06-19 02:45:46 -070013#include <cctype>
George Liu83409572019-12-24 18:42:54 +080014#include <ctime>
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050015#include <fstream>
George Liu83409572019-12-24 18:42:54 +080016#include <iostream>
17#include <map>
George Liu83409572019-12-24 18:42:54 +080018#include <stdexcept>
19#include <string>
20#include <vector>
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050021
Riya Dixit49cfb132023-03-02 04:26:53 -060022PHOSPHOR_LOG2_USING;
23
George Liu83409572019-12-24 18:42:54 +080024namespace pldm
25{
26namespace utils
27{
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -060028
Chau Ly8fa40db2024-04-02 09:32:01 +000029using ObjectMapper = sdbusplus::client::xyz::openbmc_project::ObjectMapper<>;
30
31constexpr const char* MCTP_INTERFACE_CC = "au.com.codeconstruct.MCTP.Endpoint1";
32constexpr const char* MCTP_ENDPOINT_RECOVER_METHOD = "Recover";
33
Patrick Williams366507c2025-02-03 14:28:01 -050034std::vector<std::vector<uint8_t>> findStateEffecterPDR(
35 uint8_t /*tid*/, uint16_t entityID, uint16_t stateSetId,
36 const pldm_pdr* repo)
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050037{
38 uint8_t* outData = nullptr;
39 uint32_t size{};
40 const pldm_pdr_record* record{};
41 std::vector<std::vector<uint8_t>> pdrs;
42 try
43 {
44 do
45 {
46 record = pldm_pdr_find_record_by_type(repo, PLDM_STATE_EFFECTER_PDR,
47 record, &outData, &size);
48 if (record)
49 {
Pavithra Barithaya39d13b72025-01-31 10:39:02 +053050 auto pdr = new (outData) pldm_state_effecter_pdr;
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050051 auto compositeEffecterCount = pdr->composite_effecter_count;
Chicago Duana7aacc32020-06-10 18:03:38 +080052 auto possible_states_start = pdr->possible_states;
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050053
54 for (auto effecters = 0x00; effecters < compositeEffecterCount;
55 effecters++)
56 {
Pavithra Barithaya39d13b72025-01-31 10:39:02 +053057 auto possibleStates = new (possible_states_start)
58 state_effecter_possible_states;
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050059 auto setId = possibleStates->state_set_id;
60 auto possibleStateSize =
61 possibleStates->possible_states_size;
62
63 if (pdr->entity_type == entityID && setId == stateSetId)
64 {
65 std::vector<uint8_t> effecter_pdr(&outData[0],
66 &outData[size]);
67 pdrs.emplace_back(std::move(effecter_pdr));
68 break;
69 }
Chicago Duana7aacc32020-06-10 18:03:38 +080070 possible_states_start += possibleStateSize + sizeof(setId) +
71 sizeof(possibleStateSize);
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050072 }
73 }
74
75 } while (record);
76 }
77 catch (const std::exception& e)
78 {
Riya Dixit76f2c602024-03-28 07:34:12 -050079 error("Failed to obtain a record, error - {ERROR}", "ERROR", e);
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050080 }
81
82 return pdrs;
83}
84
Patrick Williams366507c2025-02-03 14:28:01 -050085std::vector<std::vector<uint8_t>> findStateSensorPDR(
86 uint8_t /*tid*/, uint16_t entityID, uint16_t stateSetId,
87 const pldm_pdr* repo)
Chicago Duan738e4d82020-05-28 16:39:19 +080088{
89 uint8_t* outData = nullptr;
90 uint32_t size{};
91 const pldm_pdr_record* record{};
92 std::vector<std::vector<uint8_t>> pdrs;
93 try
94 {
95 do
96 {
97 record = pldm_pdr_find_record_by_type(repo, PLDM_STATE_SENSOR_PDR,
98 record, &outData, &size);
99 if (record)
100 {
Pavithra Barithaya39d13b72025-01-31 10:39:02 +0530101 auto pdr = new (outData) pldm_state_sensor_pdr;
Chicago Duan738e4d82020-05-28 16:39:19 +0800102 auto compositeSensorCount = pdr->composite_sensor_count;
Chicago Duana7aacc32020-06-10 18:03:38 +0800103 auto possible_states_start = pdr->possible_states;
Chicago Duan738e4d82020-05-28 16:39:19 +0800104
105 for (auto sensors = 0x00; sensors < compositeSensorCount;
106 sensors++)
107 {
Pavithra Barithaya39d13b72025-01-31 10:39:02 +0530108 auto possibleStates = new (possible_states_start)
109 state_sensor_possible_states;
Chicago Duan738e4d82020-05-28 16:39:19 +0800110 auto setId = possibleStates->state_set_id;
111 auto possibleStateSize =
112 possibleStates->possible_states_size;
113
114 if (pdr->entity_type == entityID && setId == stateSetId)
115 {
116 std::vector<uint8_t> sensor_pdr(&outData[0],
117 &outData[size]);
118 pdrs.emplace_back(std::move(sensor_pdr));
119 break;
120 }
Chicago Duana7aacc32020-06-10 18:03:38 +0800121 possible_states_start += possibleStateSize + sizeof(setId) +
122 sizeof(possibleStateSize);
Chicago Duan738e4d82020-05-28 16:39:19 +0800123 }
124 }
125
126 } while (record);
127 }
128 catch (const std::exception& e)
129 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500130 error(
131 "Failed to obtain a record with entity ID '{ENTITYID}', error - {ERROR}",
132 "ENTITYID", entityID, "ERROR", e);
Chicago Duan738e4d82020-05-28 16:39:19 +0800133 }
134
135 return pdrs;
136}
137
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500138uint8_t readHostEID()
139{
140 uint8_t eid{};
Brad Bishop06052cc2021-08-16 15:17:16 -0400141 std::ifstream eidFile{HOST_EID_PATH};
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500142 if (!eidFile.good())
143 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500144 error("Failed to open remote terminus EID file at path '{PATH}'",
145 "PATH", static_cast<std::string>(HOST_EID_PATH));
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500146 }
147 else
148 {
149 std::string eidStr;
150 eidFile >> eidStr;
151 if (!eidStr.empty())
152 {
153 eid = atoi(eidStr.c_str());
154 }
155 else
156 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500157 error("Remote terminus EID file was empty");
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500158 }
159 }
160
161 return eid;
162}
George Liu83409572019-12-24 18:42:54 +0800163
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000164bool isValidEID(eid mctpEid)
165{
166 if (mctpEid == MCTP_ADDR_NULL || mctpEid < MCTP_START_VALID_EID ||
167 mctpEid == MCTP_ADDR_ANY)
168 {
169 return false;
170 }
171
172 return true;
173}
174
George Liu83409572019-12-24 18:42:54 +0800175uint8_t getNumPadBytes(uint32_t data)
176{
177 uint8_t pad;
178 pad = ((data % 4) ? (4 - data % 4) : 0);
179 return pad;
180} // end getNumPadBytes
181
182bool uintToDate(uint64_t data, uint16_t* year, uint8_t* month, uint8_t* day,
183 uint8_t* hour, uint8_t* min, uint8_t* sec)
184{
185 constexpr uint64_t max_data = 29991231115959;
186 constexpr uint64_t min_data = 19700101000000;
187 if (data < min_data || data > max_data)
188 {
189 return false;
190 }
191
192 *year = data / 10000000000;
193 data = data % 10000000000;
194 *month = data / 100000000;
195 data = data % 100000000;
196 *day = data / 1000000;
197 data = data % 1000000;
198 *hour = data / 10000;
199 data = data % 10000;
200 *min = data / 100;
201 *sec = data % 100;
202
203 return true;
204}
205
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400206std::optional<std::vector<set_effecter_state_field>> parseEffecterData(
207 const std::vector<uint8_t>& effecterData, uint8_t effecterCount)
George Liu83409572019-12-24 18:42:54 +0800208{
George Liuba4c1fb2020-02-05 14:13:30 +0800209 std::vector<set_effecter_state_field> stateField;
210
211 if (effecterData.size() != effecterCount * 2)
George Liu83409572019-12-24 18:42:54 +0800212 {
George Liuba4c1fb2020-02-05 14:13:30 +0800213 return std::nullopt;
George Liu83409572019-12-24 18:42:54 +0800214 }
215
George Liuba4c1fb2020-02-05 14:13:30 +0800216 for (uint8_t i = 0; i < effecterCount; ++i)
George Liu83409572019-12-24 18:42:54 +0800217 {
George Liuba4c1fb2020-02-05 14:13:30 +0800218 uint8_t set_request = effecterData[i * 2] == PLDM_REQUEST_SET
219 ? PLDM_REQUEST_SET
220 : PLDM_NO_CHANGE;
221 set_effecter_state_field filed{set_request, effecterData[i * 2 + 1]};
222 stateField.emplace_back(std::move(filed));
George Liu83409572019-12-24 18:42:54 +0800223 }
224
George Liuba4c1fb2020-02-05 14:13:30 +0800225 return std::make_optional(std::move(stateField));
George Liu83409572019-12-24 18:42:54 +0800226}
227
George Liu0e02c322020-01-01 09:41:51 +0800228std::string DBusHandler::getService(const char* path,
229 const char* interface) const
George Liu83409572019-12-24 18:42:54 +0800230{
231 using DbusInterfaceList = std::vector<std::string>;
232 std::map<std::string, std::vector<std::string>> mapperResponse;
George Liu0e02c322020-01-01 09:41:51 +0800233 auto& bus = DBusHandler::getBus();
George Liu83409572019-12-24 18:42:54 +0800234
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -0600235 auto mapper = bus.new_method_call(ObjectMapper::default_service,
236 ObjectMapper::instance_path,
237 ObjectMapper::interface, "GetObject");
George Liudf9a6d32020-12-22 16:27:16 +0800238
239 if (interface)
240 {
241 mapper.append(path, DbusInterfaceList({interface}));
242 }
243 else
244 {
245 mapper.append(path, DbusInterfaceList({}));
246 }
George Liu83409572019-12-24 18:42:54 +0800247
vkaverap@in.ibm.com91a092f2023-09-18 23:39:44 -0500248 auto mapperResponseMsg = bus.call(mapper, dbusTimeout);
George Liu0e02c322020-01-01 09:41:51 +0800249 mapperResponseMsg.read(mapperResponse);
George Liu83409572019-12-24 18:42:54 +0800250 return mapperResponse.begin()->first;
251}
252
Patrick Williams366507c2025-02-03 14:28:01 -0500253GetSubTreeResponse DBusHandler::getSubtree(
254 const std::string& searchPath, int depth,
255 const std::vector<std::string>& ifaceList) const
Manojkiran Eda1ef62c32021-04-24 07:23:18 +0530256{
Manojkiran Eda1ef62c32021-04-24 07:23:18 +0530257 auto& bus = pldm::utils::DBusHandler::getBus();
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -0600258 auto method = bus.new_method_call(ObjectMapper::default_service,
259 ObjectMapper::instance_path,
260 ObjectMapper::interface, "GetSubTree");
Manojkiran Eda1ef62c32021-04-24 07:23:18 +0530261 method.append(searchPath, depth, ifaceList);
vkaverap@in.ibm.com91a092f2023-09-18 23:39:44 -0500262 auto reply = bus.call(method, dbusTimeout);
Manojkiran Eda1ef62c32021-04-24 07:23:18 +0530263 GetSubTreeResponse response;
264 reply.read(response);
265 return response;
266}
267
Pavithra Barithaya2ec82692024-04-29 06:31:10 -0500268GetSubTreePathsResponse DBusHandler::getSubTreePaths(
269 const std::string& objectPath, int depth,
270 const std::vector<std::string>& ifaceList) const
271{
272 std::vector<std::string> paths;
273 auto& bus = pldm::utils::DBusHandler::getBus();
274 auto method = bus.new_method_call(
275 ObjectMapper::default_service, ObjectMapper::instance_path,
276 ObjectMapper::interface, "GetSubTreePaths");
277 method.append(objectPath, depth, ifaceList);
278 auto reply = bus.call(method, dbusTimeout);
279
280 reply.read(paths);
281 return paths;
282}
283
Delphine CC Chiu549e4bc2024-03-06 11:24:05 +0800284GetAncestorsResponse DBusHandler::getAncestors(
285 const std::string& path, const std::vector<std::string>& ifaceList) const
286{
287 auto& bus = pldm::utils::DBusHandler::getBus();
288 auto method = bus.new_method_call(ObjectMapper::default_service,
289 ObjectMapper::instance_path,
290 ObjectMapper::interface, "GetAncestors");
291 method.append(path, ifaceList);
292 auto reply = bus.call(method, dbusTimeout);
293 GetAncestorsResponse response;
294 reply.read(response);
295 return response;
296}
297
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530298void reportError(const char* errorMsg)
George Liu83409572019-12-24 18:42:54 +0800299{
George Liu0e02c322020-01-01 09:41:51 +0800300 auto& bus = pldm::utils::DBusHandler::getBus();
Riya Dixit76f2c602024-03-28 07:34:12 -0500301 using LoggingCreate =
302 sdbusplus::client::xyz::openbmc_project::logging::Create<>;
George Liu83409572019-12-24 18:42:54 +0800303 try
304 {
George Liu83409572019-12-24 18:42:54 +0800305 using namespace sdbusplus::xyz::openbmc_project::Logging::server;
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530306 auto severity =
307 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
308 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
309 Error);
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -0600310 auto method = bus.new_method_call(LoggingCreate::default_service,
311 LoggingCreate::instance_path,
312 LoggingCreate::interface, "Create");
313
George Liu83409572019-12-24 18:42:54 +0800314 std::map<std::string, std::string> addlData{};
315 method.append(errorMsg, severity, addlData);
vkaverap@in.ibm.com5b71b862023-08-21 05:19:04 +0000316 bus.call_noreply(method, dbusTimeout);
George Liu83409572019-12-24 18:42:54 +0800317 }
318 catch (const std::exception& e)
319 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600320 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500321 "Failed to do dbus call for creating error log for '{ERRMSG}' at path '{PATH}' and interface '{INTERFACE}', error - {ERROR}",
322 "ERRMSG", errorMsg, "PATH", LoggingCreate::instance_path,
323 "INTERFACE", LoggingCreate::interface, "ERROR", e);
George Liu83409572019-12-24 18:42:54 +0800324 }
325}
326
George Liu1e44c732020-02-28 20:20:06 +0800327void DBusHandler::setDbusProperty(const DBusMapping& dBusMap,
328 const PropertyValue& value) const
329{
330 auto setDbusValue = [&dBusMap, this](const auto& variant) {
331 auto& bus = getBus();
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400332 auto service =
333 getService(dBusMap.objectPath.c_str(), dBusMap.interface.c_str());
George Liu1e44c732020-02-28 20:20:06 +0800334 auto method = bus.new_method_call(
335 service.c_str(), dBusMap.objectPath.c_str(), dbusProperties, "Set");
336 method.append(dBusMap.interface.c_str(), dBusMap.propertyName.c_str(),
337 variant);
vkaverap@in.ibm.com5b71b862023-08-21 05:19:04 +0000338 bus.call_noreply(method, dbusTimeout);
George Liu1e44c732020-02-28 20:20:06 +0800339 };
340
341 if (dBusMap.propertyType == "uint8_t")
342 {
343 std::variant<uint8_t> v = std::get<uint8_t>(value);
344 setDbusValue(v);
345 }
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600346 else if (dBusMap.propertyType == "bool")
347 {
348 std::variant<bool> v = std::get<bool>(value);
349 setDbusValue(v);
350 }
George Liu1e44c732020-02-28 20:20:06 +0800351 else if (dBusMap.propertyType == "int16_t")
352 {
353 std::variant<int16_t> v = std::get<int16_t>(value);
354 setDbusValue(v);
355 }
356 else if (dBusMap.propertyType == "uint16_t")
357 {
358 std::variant<uint16_t> v = std::get<uint16_t>(value);
359 setDbusValue(v);
360 }
361 else if (dBusMap.propertyType == "int32_t")
362 {
363 std::variant<int32_t> v = std::get<int32_t>(value);
364 setDbusValue(v);
365 }
366 else if (dBusMap.propertyType == "uint32_t")
367 {
368 std::variant<uint32_t> v = std::get<uint32_t>(value);
369 setDbusValue(v);
370 }
371 else if (dBusMap.propertyType == "int64_t")
372 {
373 std::variant<int64_t> v = std::get<int64_t>(value);
374 setDbusValue(v);
375 }
376 else if (dBusMap.propertyType == "uint64_t")
377 {
378 std::variant<uint64_t> v = std::get<uint64_t>(value);
379 setDbusValue(v);
380 }
381 else if (dBusMap.propertyType == "double")
382 {
383 std::variant<double> v = std::get<double>(value);
384 setDbusValue(v);
385 }
386 else if (dBusMap.propertyType == "string")
387 {
388 std::variant<std::string> v = std::get<std::string>(value);
389 setDbusValue(v);
390 }
Sora Sua8231fd2025-08-06 14:20:49 +0800391 else if (dBusMap.propertyType == "array[string]")
392 {
393 std::variant<std::vector<std::string>> v =
394 std::get<std::vector<std::string>>(value);
395 setDbusValue(v);
396 }
George Liu1e44c732020-02-28 20:20:06 +0800397 else
398 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500399 error("Unsupported property type '{TYPE}'", "TYPE",
400 dBusMap.propertyType);
401 throw std::invalid_argument("UnSupported Dbus Type");
George Liu1e44c732020-02-28 20:20:06 +0800402 }
403}
404
John Wang9e242422020-03-05 08:37:50 +0800405PropertyValue DBusHandler::getDbusPropertyVariant(
406 const char* objPath, const char* dbusProp, const char* dbusInterface) const
407{
408 auto& bus = DBusHandler::getBus();
409 auto service = getService(objPath, dbusInterface);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400410 auto method =
411 bus.new_method_call(service.c_str(), objPath, dbusProperties, "Get");
John Wang9e242422020-03-05 08:37:50 +0800412 method.append(dbusInterface, dbusProp);
Patrick Williams75b8f462024-02-07 10:59:26 -0600413 return bus.call(method, dbusTimeout).unpack<PropertyValue>();
John Wang9e242422020-03-05 08:37:50 +0800414}
415
Unive Tienc40d4a62025-03-12 11:36:07 +0800416GetAssociatedSubTreeResponse DBusHandler::getAssociatedSubTree(
417 const sdbusplus::message::object_path& objectPath,
418 const sdbusplus::message::object_path& subtree, int depth,
419 const std::vector<std::string>& ifaceList) const
420{
421 auto& bus = DBusHandler::getBus();
422 auto method = bus.new_method_call(
423 ObjectMapper::default_service, ObjectMapper::instance_path,
424 ObjectMapper::interface, "GetAssociatedSubTree");
425 method.append(objectPath, subtree, depth, ifaceList);
426 auto reply = bus.call(method, dbusTimeout);
427 GetAssociatedSubTreeResponse response;
428 reply.read(response);
429 return response;
430}
431
Riya Dixit754041d2024-02-20 06:15:49 -0600432ObjectValueTree DBusHandler::getManagedObj(const char* service,
433 const char* rootPath)
434{
435 auto& bus = DBusHandler::getBus();
436 auto method = bus.new_method_call(service, rootPath,
437 "org.freedesktop.DBus.ObjectManager",
438 "GetManagedObjects");
439 return bus.call(method).unpack<ObjectValueTree>();
440}
441
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400442PropertyMap DBusHandler::getDbusPropertiesVariant(
443 const char* serviceName, const char* objPath,
444 const char* dbusInterface) const
Gilbert Chen44524a52022-02-14 12:12:25 +0000445{
446 auto& bus = DBusHandler::getBus();
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400447 auto method =
448 bus.new_method_call(serviceName, objPath, dbusProperties, "GetAll");
Gilbert Chen44524a52022-02-14 12:12:25 +0000449 method.append(dbusInterface);
450 return bus.call(method, dbusTimeout).unpack<PropertyMap>();
451}
452
TOM JOSEPHd4d97a52020-03-23 14:36:34 +0530453PropertyValue jsonEntryToDbusVal(std::string_view type,
454 const nlohmann::json& value)
455{
456 PropertyValue propValue{};
457 if (type == "uint8_t")
458 {
459 propValue = static_cast<uint8_t>(value);
460 }
461 else if (type == "uint16_t")
462 {
463 propValue = static_cast<uint16_t>(value);
464 }
465 else if (type == "uint32_t")
466 {
467 propValue = static_cast<uint32_t>(value);
468 }
469 else if (type == "uint64_t")
470 {
471 propValue = static_cast<uint64_t>(value);
472 }
473 else if (type == "int16_t")
474 {
475 propValue = static_cast<int16_t>(value);
476 }
477 else if (type == "int32_t")
478 {
479 propValue = static_cast<int32_t>(value);
480 }
481 else if (type == "int64_t")
482 {
483 propValue = static_cast<int64_t>(value);
484 }
485 else if (type == "bool")
486 {
487 propValue = static_cast<bool>(value);
488 }
489 else if (type == "double")
490 {
491 propValue = static_cast<double>(value);
492 }
493 else if (type == "string")
494 {
495 propValue = static_cast<std::string>(value);
496 }
497 else
498 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500499 error("Unknown D-Bus property type '{TYPE}'", "TYPE", type);
TOM JOSEPHd4d97a52020-03-23 14:36:34 +0530500 }
501
502 return propValue;
503}
504
Tom Joseph250c4752020-04-15 10:32:45 +0530505uint16_t findStateEffecterId(const pldm_pdr* pdrRepo, uint16_t entityType,
506 uint16_t entityInstance, uint16_t containerId,
Sampa Misraa4a96162020-07-14 05:33:46 -0500507 uint16_t stateSetId, bool localOrRemote)
Tom Joseph250c4752020-04-15 10:32:45 +0530508{
509 uint8_t* pdrData = nullptr;
510 uint32_t pdrSize{};
511 const pldm_pdr_record* record{};
512 do
513 {
514 record = pldm_pdr_find_record_by_type(pdrRepo, PLDM_STATE_EFFECTER_PDR,
515 record, &pdrData, &pdrSize);
Sampa Misraa4a96162020-07-14 05:33:46 -0500516 if (record && (localOrRemote ^ pldm_pdr_record_is_remote(record)))
Tom Joseph250c4752020-04-15 10:32:45 +0530517 {
Pavithra Barithaya39d13b72025-01-31 10:39:02 +0530518 auto pdr = new (pdrData) pldm_state_effecter_pdr;
Tom Joseph250c4752020-04-15 10:32:45 +0530519 auto compositeEffecterCount = pdr->composite_effecter_count;
520 auto possible_states_start = pdr->possible_states;
521
522 for (auto effecters = 0x00; effecters < compositeEffecterCount;
523 effecters++)
524 {
Pavithra Barithaya39d13b72025-01-31 10:39:02 +0530525 auto possibleStates = new (possible_states_start)
526 state_effecter_possible_states;
Tom Joseph250c4752020-04-15 10:32:45 +0530527 auto setId = possibleStates->state_set_id;
528 auto possibleStateSize = possibleStates->possible_states_size;
529
530 if (entityType == pdr->entity_type &&
531 entityInstance == pdr->entity_instance &&
532 containerId == pdr->container_id && stateSetId == setId)
533 {
534 return pdr->effecter_id;
535 }
536 possible_states_start += possibleStateSize + sizeof(setId) +
537 sizeof(possibleStateSize);
538 }
539 }
540 } while (record);
541
542 return PLDM_INVALID_EFFECTER_ID;
543}
544
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800545int emitStateSensorEventSignal(uint8_t tid, uint16_t sensorId,
546 uint8_t sensorOffset, uint8_t eventState,
547 uint8_t previousEventState)
548{
549 try
550 {
551 auto& bus = DBusHandler::getBus();
552 auto msg = bus.new_signal("/xyz/openbmc_project/pldm",
553 "xyz.openbmc_project.PLDM.Event",
554 "StateSensorEvent");
555 msg.append(tid, sensorId, sensorOffset, eventState, previousEventState);
556
557 msg.signal_send();
558 }
Patrick Williams51330582021-10-06 12:48:56 -0500559 catch (const std::exception& e)
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800560 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500561 error("Failed to emit pldm event signal, error - {ERROR}", "ERROR", e);
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800562 return PLDM_ERROR;
563 }
564
565 return PLDM_SUCCESS;
566}
567
Chau Ly8fa40db2024-04-02 09:32:01 +0000568void recoverMctpEndpoint(const std::string& endpointObjPath)
569{
570 auto& bus = DBusHandler::getBus();
571 try
572 {
573 std::string service = DBusHandler().getService(endpointObjPath.c_str(),
574 MCTP_INTERFACE_CC);
575
576 auto method = bus.new_method_call(
577 service.c_str(), endpointObjPath.c_str(), MCTP_INTERFACE_CC,
578 MCTP_ENDPOINT_RECOVER_METHOD);
579 bus.call_noreply(method, dbusTimeout);
580 }
581 catch (const std::exception& e)
582 {
583 error(
584 "failed to make a D-Bus call to recover MCTP Endpoint, ERROR {ERR_EXCEP}",
585 "ERR_EXCEP", e);
586 }
587}
588
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500589uint16_t findStateSensorId(const pldm_pdr* pdrRepo, uint8_t tid,
590 uint16_t entityType, uint16_t entityInstance,
591 uint16_t containerId, uint16_t stateSetId)
592{
593 auto pdrs = findStateSensorPDR(tid, entityType, stateSetId, pdrRepo);
594 for (auto pdr : pdrs)
595 {
Pavithra Barithaya39d13b72025-01-31 10:39:02 +0530596 auto sensorPdr = new (pdr.data()) pldm_state_sensor_pdr;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500597 auto compositeSensorCount = sensorPdr->composite_sensor_count;
598 auto possible_states_start = sensorPdr->possible_states;
599
600 for (auto sensors = 0x00; sensors < compositeSensorCount; sensors++)
601 {
Pavithra Barithaya39d13b72025-01-31 10:39:02 +0530602 auto possibleStates = new (possible_states_start)
603 state_sensor_possible_states;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500604 auto setId = possibleStates->state_set_id;
605 auto possibleStateSize = possibleStates->possible_states_size;
606 if (entityType == sensorPdr->entity_type &&
607 entityInstance == sensorPdr->entity_instance &&
608 stateSetId == setId && containerId == sensorPdr->container_id)
609 {
610 return sensorPdr->sensor_id;
611 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400612 possible_states_start +=
613 possibleStateSize + sizeof(setId) + sizeof(possibleStateSize);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500614 }
615 }
616 return PLDM_INVALID_EFFECTER_ID;
617}
618
Tom Josephe5268cd2021-09-07 13:04:03 +0530619void printBuffer(bool isTx, const std::vector<uint8_t>& buffer)
Sridevi Rameshae28bc72020-12-10 07:21:16 -0600620{
Manojkiran Edacd4cd452024-04-23 08:53:17 +0530621 if (buffer.empty())
Sridevi Rameshae28bc72020-12-10 07:21:16 -0600622 {
Manojkiran Edacd4cd452024-04-23 08:53:17 +0530623 return;
Sridevi Rameshae28bc72020-12-10 07:21:16 -0600624 }
Manojkiran Edacd4cd452024-04-23 08:53:17 +0530625
626 std::cout << (isTx ? "Tx: " : "Rx: ");
627
628 std::ranges::for_each(buffer, [](uint8_t byte) {
629 std::cout << std::format("{:02x} ", byte);
630 });
631
632 std::cout << std::endl;
Sridevi Rameshae28bc72020-12-10 07:21:16 -0600633}
634
Tom Joseph54922072021-06-19 02:45:46 -0700635std::string toString(const struct variable_field& var)
636{
637 if (var.ptr == nullptr || !var.length)
638 {
639 return "";
640 }
641
642 std::string str(reinterpret_cast<const char*>(var.ptr), var.length);
643 std::replace_if(
644 str.begin(), str.end(), [](const char& c) { return !isprint(c); }, ' ');
645 return str;
646}
647
George Liu872f0f62021-11-25 16:26:16 +0800648std::vector<std::string> split(std::string_view srcStr, std::string_view delim,
649 std::string_view trimStr)
650{
651 std::vector<std::string> out;
George Liua9eacff2025-08-25 11:20:52 +0800652 size_t start = 0;
George Liu872f0f62021-11-25 16:26:16 +0800653 size_t end = 0;
654
655 while ((start = srcStr.find_first_not_of(delim, end)) != std::string::npos)
656 {
657 end = srcStr.find(delim, start);
658 std::string_view dstStr = srcStr.substr(start, end - start);
659 if (!trimStr.empty())
660 {
661 dstStr.remove_prefix(dstStr.find_first_not_of(trimStr));
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400662 dstStr.remove_suffix(
663 dstStr.size() - 1 - dstStr.find_last_not_of(trimStr));
George Liu872f0f62021-11-25 16:26:16 +0800664 }
665
666 if (!dstStr.empty())
667 {
George Liua9eacff2025-08-25 11:20:52 +0800668 out.emplace_back(dstStr);
George Liu872f0f62021-11-25 16:26:16 +0800669 }
670 }
671
672 return out;
673}
674
Manojkiran Edaef773052021-07-29 09:29:28 +0530675std::string getCurrentSystemTime()
676{
Manojkiran Eda09a89822024-04-24 11:02:44 +0530677 const auto zonedTime{std::chrono::zoned_time{
678 std::chrono::current_zone(), std::chrono::system_clock::now()}};
679 return std::format("{:%F %Z %T}", zonedTime);
Manojkiran Edaef773052021-07-29 09:29:28 +0530680}
681
Sridevi Ramesheefe49b2022-06-27 11:51:02 -0500682bool checkForFruPresence(const std::string& objPath)
683{
684 bool isPresent = false;
685 static constexpr auto presentInterface =
686 "xyz.openbmc_project.Inventory.Item";
687 static constexpr auto presentProperty = "Present";
688 try
689 {
690 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
691 objPath.c_str(), presentProperty, presentInterface);
692 isPresent = std::get<bool>(propVal);
693 }
694 catch (const sdbusplus::exception::SdBusError& e)
695 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500696 error("Failed to check for FRU presence at {PATH}, error - {ERROR}",
697 "PATH", objPath, "ERROR", e);
Sridevi Ramesheefe49b2022-06-27 11:51:02 -0500698 }
699 return isPresent;
700}
701
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600702bool checkIfLogicalBitSet(const uint16_t& containerId)
703{
704 return !(containerId & 0x8000);
705}
706
Pavithra Barithaya5e542be2021-08-13 00:33:31 -0500707void setFruPresence(const std::string& fruObjPath, bool present)
708{
709 pldm::utils::PropertyValue value{present};
710 pldm::utils::DBusMapping dbusMapping;
711 dbusMapping.objectPath = fruObjPath;
712 dbusMapping.interface = "xyz.openbmc_project.Inventory.Item";
713 dbusMapping.propertyName = "Present";
714 dbusMapping.propertyType = "bool";
715 try
716 {
717 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
718 }
719 catch (const std::exception& e)
720 {
721 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500722 "Failed to set the present property on path '{PATH}', error - {ERROR}.",
Pavithra Barithaya5e542be2021-08-13 00:33:31 -0500723 "PATH", fruObjPath, "ERROR", e);
724 }
725}
726
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000727std::string_view trimNameForDbus(std::string& name)
728{
729 std::replace(name.begin(), name.end(), ' ', '_');
730 auto nullTerminatorPos = name.find('\0');
731 if (nullTerminatorPos != std::string::npos)
732 {
733 name.erase(nullTerminatorPos);
734 }
735 return name;
736}
Thu Nguyena34a64b2022-03-31 08:56:39 +0700737
738bool dbusPropValuesToDouble(const std::string_view& type,
739 const pldm::utils::PropertyValue& value,
740 double* doubleValue)
741{
742 if (!dbusValueNumericTypeNames.contains(type))
743 {
744 return false;
745 }
746
747 if (!doubleValue)
748 {
749 return false;
750 }
751
752 try
753 {
754 if (type == "uint8_t")
755 {
756 *doubleValue = static_cast<double>(std::get<uint8_t>(value));
757 }
758 else if (type == "int16_t")
759 {
760 *doubleValue = static_cast<double>(std::get<int16_t>(value));
761 }
762 else if (type == "uint16_t")
763 {
764 *doubleValue = static_cast<double>(std::get<uint16_t>(value));
765 }
766 else if (type == "int32_t")
767 {
768 *doubleValue = static_cast<double>(std::get<int32_t>(value));
769 }
770 else if (type == "uint32_t")
771 {
772 *doubleValue = static_cast<double>(std::get<uint32_t>(value));
773 }
774 else if (type == "int64_t")
775 {
776 *doubleValue = static_cast<double>(std::get<int64_t>(value));
777 }
778 else if (type == "uint64_t")
779 {
780 *doubleValue = static_cast<double>(std::get<uint64_t>(value));
781 }
782 else if (type == "double")
783 {
784 *doubleValue = static_cast<double>(std::get<double>(value));
785 }
786 else
787 {
788 return false;
789 }
790 }
791 catch (const std::exception& e)
792 {
793 return false;
794 }
795
796 return true;
797}
Dung Caob6d39432024-06-05 03:46:47 +0000798
Patrick Williams366507c2025-02-03 14:28:01 -0500799std::optional<std::string> fruFieldValuestring(const uint8_t* value,
800 const uint8_t& length)
Dung Caob6d39432024-06-05 03:46:47 +0000801{
802 if (!value || !length)
803 {
Dung Caob6d39432024-06-05 03:46:47 +0000804 return std::nullopt;
805 }
806
807 return std::string(reinterpret_cast<const char*>(value), length);
808}
809
810std::optional<uint32_t> fruFieldParserU32(const uint8_t* value,
811 const uint8_t& length)
812{
813 if (!value || length != sizeof(uint32_t))
814 {
815 lg2::error("Fru data to u32 invalid data.");
816 return std::nullopt;
817 }
818
819 uint32_t ret;
820 std::memcpy(&ret, value, length);
821 return ret;
822}
823
Pavithra Barithaya36ac5592025-06-16 11:41:37 +0530824SensorPDRs getStateSensorPDRsByType(uint16_t entityType, const pldm_pdr* repo)
825{
826 uint8_t* outData = nullptr;
827 uint32_t size{};
828 const pldm_pdr_record* record = nullptr;
829 SensorPDRs pdrs;
830
831 if (repo)
832 {
833 while ((record = pldm_pdr_find_record_by_type(
834 repo, PLDM_STATE_SENSOR_PDR, record, &outData, &size)))
835 {
836 auto pdr = new (outData) pldm_state_sensor_pdr;
837 if (pdr && pdr->entity_type == entityType)
838 {
839 pdrs.emplace_back(outData, outData + size);
840 }
841 }
842 }
843
844 return pdrs;
845}
846
847std::vector<pldm::pdr::SensorID> findSensorIds(
848 const pldm_pdr* pdrRepo, uint16_t entityType, uint16_t entityInstance,
849 uint16_t containerId)
850{
851 std::vector<uint16_t> sensorIDs;
852 auto pdrs = getStateSensorPDRsByType(entityType, pdrRepo);
853
854 for (const auto& pdr : pdrs)
855 {
856 auto sensorPdr =
857 reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
858
859 if (sensorPdr && sensorPdr->entity_type == entityType &&
860 sensorPdr->entity_instance == entityInstance &&
861 sensorPdr->container_id == containerId)
862 {
863 sensorIDs.emplace_back(sensorPdr->sensor_id);
864 }
865 }
866
867 return sensorIDs;
868}
869
Pavithra Barithayaa206b602025-08-21 14:37:13 +0530870EffecterPDRs getStateEffecterPDRsByType(uint16_t entityType,
871 const pldm_pdr* repo)
872{
873 uint8_t* outData = nullptr;
874 uint32_t size{};
875 const pldm_pdr_record* record = nullptr;
876 EffecterPDRs pdrs;
877 if (repo)
878 {
879 while ((record = pldm_pdr_find_record_by_type(
880 repo, PLDM_STATE_EFFECTER_PDR, record, &outData, &size)))
881 {
882 auto pdr = new (outData) pldm_state_effecter_pdr;
883 if (pdr && pdr->entity_type == entityType)
884 {
885 pdrs.emplace_back(outData, outData + size);
886 }
887 }
888 }
889 return pdrs;
890}
891
892std::vector<pldm::pdr::EffecterID> findEffecterIds(
893 const pldm_pdr* pdrRepo, uint16_t entityType, uint16_t entityInstance,
894 uint16_t containerId)
895{
896 std::vector<uint16_t> effecterIDs;
897 auto pdrs = getStateEffecterPDRsByType(entityType, pdrRepo);
898 for (const auto& pdr : pdrs)
899 {
900 auto effecterPdr =
901 reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data());
902 if (effecterPdr && effecterPdr->entity_type == entityType &&
903 effecterPdr->entity_instance == entityInstance &&
904 effecterPdr->container_id == containerId)
905 {
906 effecterIDs.emplace_back(effecterPdr->effecter_id);
907 }
908 }
909 return effecterIDs;
910}
911
Archana Kakanie26d13f2025-03-09 23:17:46 -0500912void setBiosAttr(const PendingAttributesList& biosAttrList)
913{
914 static constexpr auto SYSTEMD_PROPERTY_INTERFACE =
915 "org.freedesktop.DBus.Properties";
916 constexpr auto biosConfigPath = "/xyz/openbmc_project/bios_config/manager";
917 constexpr auto biosConfigIntf = "xyz.openbmc_project.BIOSConfig.Manager";
918
919 for (const auto& [attrName, biosAttrDetails] : biosAttrList)
920 {
921 auto& bus = DBusHandler::getBus();
922 try
923 {
924 auto service = pldm::utils::DBusHandler().getService(
925 biosConfigPath, biosConfigIntf);
926 auto method =
927 bus.new_method_call(service.c_str(), biosConfigPath,
928 SYSTEMD_PROPERTY_INTERFACE, "Set");
929 method.append(biosConfigIntf, "PendingAttributes",
930 std::variant<PendingAttributesList>(biosAttrList));
931 bus.call_noreply(method, dbusTimeout);
932 }
933 catch (const sdbusplus::exception::SdBusError& e)
934 {
935 AttributeType attrType;
936 AttributeValue attrValue;
937 std::tie(attrType, attrValue) = biosAttrDetails;
938 if (attrType ==
939 "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Integer")
940 {
941 info(
942 "Error setting the value {VALUE} to bios attribute {BIOS_ATTR}: {ERR_EXCEP}",
943 "VALUE", std::get<int64_t>(attrValue), "BIOS_ATTR",
944 attrName, "ERR_EXCEP", e);
945 }
946 else
947 {
948 info(
949 "Error setting the value {VALUE} to bios attribute {BIOS_ATTR}: {ERR_EXCEP}",
950 "VALUE", std::get<std::string>(attrValue), "BIOS_ATTR",
951 attrName, "ERR_EXCEP", e);
952 }
953 }
954 }
955}
Unive Tien7ad45b42025-08-18 06:04:53 +0000956
957long int generateSwId()
958{
959 return random() % 10000;
960}
961
George Liu83409572019-12-24 18:42:54 +0800962} // namespace utils
963} // namespace pldm