blob: 11ce06466fd740917ae4c39cdd4b7a25dca591f9 [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
Riya Dixit49cfb132023-03-02 04:26:53 -06007#include <phosphor-logging/lg2.hpp>
George Liu6492f522020-06-16 10:34:05 +08008#include <xyz/openbmc_project/Common/error.hpp>
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -06009#include <xyz/openbmc_project/Logging/Create/client.hpp>
10#include <xyz/openbmc_project/ObjectMapper/client.hpp>
George Liu6492f522020-06-16 10:34:05 +080011
Tom Joseph54922072021-06-19 02:45:46 -070012#include <algorithm>
George Liu83409572019-12-24 18:42:54 +080013#include <array>
Tom Joseph54922072021-06-19 02:45:46 -070014#include <cctype>
George Liu83409572019-12-24 18:42:54 +080015#include <ctime>
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050016#include <fstream>
George Liu83409572019-12-24 18:42:54 +080017#include <iostream>
18#include <map>
George Liu83409572019-12-24 18:42:54 +080019#include <stdexcept>
20#include <string>
21#include <vector>
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050022
Riya Dixit49cfb132023-03-02 04:26:53 -060023PHOSPHOR_LOG2_USING;
24
George Liu83409572019-12-24 18:42:54 +080025namespace pldm
26{
27namespace utils
28{
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -060029
Chau Ly8fa40db2024-04-02 09:32:01 +000030using ObjectMapper = sdbusplus::client::xyz::openbmc_project::ObjectMapper<>;
31
32constexpr const char* MCTP_INTERFACE_CC = "au.com.codeconstruct.MCTP.Endpoint1";
33constexpr const char* MCTP_ENDPOINT_RECOVER_METHOD = "Recover";
34
Patrick Williams366507c2025-02-03 14:28:01 -050035std::vector<std::vector<uint8_t>> findStateEffecterPDR(
36 uint8_t /*tid*/, uint16_t entityID, uint16_t stateSetId,
37 const pldm_pdr* repo)
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050038{
39 uint8_t* outData = nullptr;
40 uint32_t size{};
41 const pldm_pdr_record* record{};
42 std::vector<std::vector<uint8_t>> pdrs;
43 try
44 {
45 do
46 {
47 record = pldm_pdr_find_record_by_type(repo, PLDM_STATE_EFFECTER_PDR,
48 record, &outData, &size);
49 if (record)
50 {
51 auto pdr = reinterpret_cast<pldm_state_effecter_pdr*>(outData);
52 auto compositeEffecterCount = pdr->composite_effecter_count;
Chicago Duana7aacc32020-06-10 18:03:38 +080053 auto possible_states_start = pdr->possible_states;
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050054
55 for (auto effecters = 0x00; effecters < compositeEffecterCount;
56 effecters++)
57 {
58 auto possibleStates =
59 reinterpret_cast<state_effecter_possible_states*>(
Chicago Duana7aacc32020-06-10 18:03:38 +080060 possible_states_start);
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050061 auto setId = possibleStates->state_set_id;
62 auto possibleStateSize =
63 possibleStates->possible_states_size;
64
65 if (pdr->entity_type == entityID && setId == stateSetId)
66 {
67 std::vector<uint8_t> effecter_pdr(&outData[0],
68 &outData[size]);
69 pdrs.emplace_back(std::move(effecter_pdr));
70 break;
71 }
Chicago Duana7aacc32020-06-10 18:03:38 +080072 possible_states_start += possibleStateSize + sizeof(setId) +
73 sizeof(possibleStateSize);
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050074 }
75 }
76
77 } while (record);
78 }
79 catch (const std::exception& e)
80 {
Riya Dixit76f2c602024-03-28 07:34:12 -050081 error("Failed to obtain a record, error - {ERROR}", "ERROR", e);
Pavithra Barithaya0f74c982020-04-27 02:17:10 -050082 }
83
84 return pdrs;
85}
86
Patrick Williams366507c2025-02-03 14:28:01 -050087std::vector<std::vector<uint8_t>> findStateSensorPDR(
88 uint8_t /*tid*/, uint16_t entityID, uint16_t stateSetId,
89 const pldm_pdr* repo)
Chicago Duan738e4d82020-05-28 16:39:19 +080090{
91 uint8_t* outData = nullptr;
92 uint32_t size{};
93 const pldm_pdr_record* record{};
94 std::vector<std::vector<uint8_t>> pdrs;
95 try
96 {
97 do
98 {
99 record = pldm_pdr_find_record_by_type(repo, PLDM_STATE_SENSOR_PDR,
100 record, &outData, &size);
101 if (record)
102 {
103 auto pdr = reinterpret_cast<pldm_state_sensor_pdr*>(outData);
104 auto compositeSensorCount = pdr->composite_sensor_count;
Chicago Duana7aacc32020-06-10 18:03:38 +0800105 auto possible_states_start = pdr->possible_states;
Chicago Duan738e4d82020-05-28 16:39:19 +0800106
107 for (auto sensors = 0x00; sensors < compositeSensorCount;
108 sensors++)
109 {
110 auto possibleStates =
111 reinterpret_cast<state_sensor_possible_states*>(
Chicago Duana7aacc32020-06-10 18:03:38 +0800112 possible_states_start);
Chicago Duan738e4d82020-05-28 16:39:19 +0800113 auto setId = possibleStates->state_set_id;
114 auto possibleStateSize =
115 possibleStates->possible_states_size;
116
117 if (pdr->entity_type == entityID && setId == stateSetId)
118 {
119 std::vector<uint8_t> sensor_pdr(&outData[0],
120 &outData[size]);
121 pdrs.emplace_back(std::move(sensor_pdr));
122 break;
123 }
Chicago Duana7aacc32020-06-10 18:03:38 +0800124 possible_states_start += possibleStateSize + sizeof(setId) +
125 sizeof(possibleStateSize);
Chicago Duan738e4d82020-05-28 16:39:19 +0800126 }
127 }
128
129 } while (record);
130 }
131 catch (const std::exception& e)
132 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500133 error(
134 "Failed to obtain a record with entity ID '{ENTITYID}', error - {ERROR}",
135 "ENTITYID", entityID, "ERROR", e);
Chicago Duan738e4d82020-05-28 16:39:19 +0800136 }
137
138 return pdrs;
139}
140
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500141uint8_t readHostEID()
142{
143 uint8_t eid{};
Brad Bishop06052cc2021-08-16 15:17:16 -0400144 std::ifstream eidFile{HOST_EID_PATH};
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500145 if (!eidFile.good())
146 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500147 error("Failed to open remote terminus EID file at path '{PATH}'",
148 "PATH", static_cast<std::string>(HOST_EID_PATH));
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500149 }
150 else
151 {
152 std::string eidStr;
153 eidFile >> eidStr;
154 if (!eidStr.empty())
155 {
156 eid = atoi(eidStr.c_str());
157 }
158 else
159 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500160 error("Remote terminus EID file was empty");
Pavithra Barithaya51efaf82020-04-02 02:42:27 -0500161 }
162 }
163
164 return eid;
165}
George Liu83409572019-12-24 18:42:54 +0800166
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000167bool isValidEID(eid mctpEid)
168{
169 if (mctpEid == MCTP_ADDR_NULL || mctpEid < MCTP_START_VALID_EID ||
170 mctpEid == MCTP_ADDR_ANY)
171 {
172 return false;
173 }
174
175 return true;
176}
177
George Liu83409572019-12-24 18:42:54 +0800178uint8_t getNumPadBytes(uint32_t data)
179{
180 uint8_t pad;
181 pad = ((data % 4) ? (4 - data % 4) : 0);
182 return pad;
183} // end getNumPadBytes
184
185bool uintToDate(uint64_t data, uint16_t* year, uint8_t* month, uint8_t* day,
186 uint8_t* hour, uint8_t* min, uint8_t* sec)
187{
188 constexpr uint64_t max_data = 29991231115959;
189 constexpr uint64_t min_data = 19700101000000;
190 if (data < min_data || data > max_data)
191 {
192 return false;
193 }
194
195 *year = data / 10000000000;
196 data = data % 10000000000;
197 *month = data / 100000000;
198 data = data % 100000000;
199 *day = data / 1000000;
200 data = data % 1000000;
201 *hour = data / 10000;
202 data = data % 10000;
203 *min = data / 100;
204 *sec = data % 100;
205
206 return true;
207}
208
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400209std::optional<std::vector<set_effecter_state_field>> parseEffecterData(
210 const std::vector<uint8_t>& effecterData, uint8_t effecterCount)
George Liu83409572019-12-24 18:42:54 +0800211{
George Liuba4c1fb2020-02-05 14:13:30 +0800212 std::vector<set_effecter_state_field> stateField;
213
214 if (effecterData.size() != effecterCount * 2)
George Liu83409572019-12-24 18:42:54 +0800215 {
George Liuba4c1fb2020-02-05 14:13:30 +0800216 return std::nullopt;
George Liu83409572019-12-24 18:42:54 +0800217 }
218
George Liuba4c1fb2020-02-05 14:13:30 +0800219 for (uint8_t i = 0; i < effecterCount; ++i)
George Liu83409572019-12-24 18:42:54 +0800220 {
George Liuba4c1fb2020-02-05 14:13:30 +0800221 uint8_t set_request = effecterData[i * 2] == PLDM_REQUEST_SET
222 ? PLDM_REQUEST_SET
223 : PLDM_NO_CHANGE;
224 set_effecter_state_field filed{set_request, effecterData[i * 2 + 1]};
225 stateField.emplace_back(std::move(filed));
George Liu83409572019-12-24 18:42:54 +0800226 }
227
George Liuba4c1fb2020-02-05 14:13:30 +0800228 return std::make_optional(std::move(stateField));
George Liu83409572019-12-24 18:42:54 +0800229}
230
George Liu0e02c322020-01-01 09:41:51 +0800231std::string DBusHandler::getService(const char* path,
232 const char* interface) const
George Liu83409572019-12-24 18:42:54 +0800233{
234 using DbusInterfaceList = std::vector<std::string>;
235 std::map<std::string, std::vector<std::string>> mapperResponse;
George Liu0e02c322020-01-01 09:41:51 +0800236 auto& bus = DBusHandler::getBus();
George Liu83409572019-12-24 18:42:54 +0800237
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -0600238 auto mapper = bus.new_method_call(ObjectMapper::default_service,
239 ObjectMapper::instance_path,
240 ObjectMapper::interface, "GetObject");
George Liudf9a6d32020-12-22 16:27:16 +0800241
242 if (interface)
243 {
244 mapper.append(path, DbusInterfaceList({interface}));
245 }
246 else
247 {
248 mapper.append(path, DbusInterfaceList({}));
249 }
George Liu83409572019-12-24 18:42:54 +0800250
vkaverap@in.ibm.com91a092f2023-09-18 23:39:44 -0500251 auto mapperResponseMsg = bus.call(mapper, dbusTimeout);
George Liu0e02c322020-01-01 09:41:51 +0800252 mapperResponseMsg.read(mapperResponse);
George Liu83409572019-12-24 18:42:54 +0800253 return mapperResponse.begin()->first;
254}
255
Patrick Williams366507c2025-02-03 14:28:01 -0500256GetSubTreeResponse DBusHandler::getSubtree(
257 const std::string& searchPath, int depth,
258 const std::vector<std::string>& ifaceList) const
Manojkiran Eda1ef62c32021-04-24 07:23:18 +0530259{
Manojkiran Eda1ef62c32021-04-24 07:23:18 +0530260 auto& bus = pldm::utils::DBusHandler::getBus();
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -0600261 auto method = bus.new_method_call(ObjectMapper::default_service,
262 ObjectMapper::instance_path,
263 ObjectMapper::interface, "GetSubTree");
Manojkiran Eda1ef62c32021-04-24 07:23:18 +0530264 method.append(searchPath, depth, ifaceList);
vkaverap@in.ibm.com91a092f2023-09-18 23:39:44 -0500265 auto reply = bus.call(method, dbusTimeout);
Manojkiran Eda1ef62c32021-04-24 07:23:18 +0530266 GetSubTreeResponse response;
267 reply.read(response);
268 return response;
269}
270
Pavithra Barithaya2ec82692024-04-29 06:31:10 -0500271GetSubTreePathsResponse DBusHandler::getSubTreePaths(
272 const std::string& objectPath, int depth,
273 const std::vector<std::string>& ifaceList) const
274{
275 std::vector<std::string> paths;
276 auto& bus = pldm::utils::DBusHandler::getBus();
277 auto method = bus.new_method_call(
278 ObjectMapper::default_service, ObjectMapper::instance_path,
279 ObjectMapper::interface, "GetSubTreePaths");
280 method.append(objectPath, depth, ifaceList);
281 auto reply = bus.call(method, dbusTimeout);
282
283 reply.read(paths);
284 return paths;
285}
286
Delphine CC Chiu549e4bc2024-03-06 11:24:05 +0800287GetAncestorsResponse DBusHandler::getAncestors(
288 const std::string& path, const std::vector<std::string>& ifaceList) const
289{
290 auto& bus = pldm::utils::DBusHandler::getBus();
291 auto method = bus.new_method_call(ObjectMapper::default_service,
292 ObjectMapper::instance_path,
293 ObjectMapper::interface, "GetAncestors");
294 method.append(path, ifaceList);
295 auto reply = bus.call(method, dbusTimeout);
296 GetAncestorsResponse response;
297 reply.read(response);
298 return response;
299}
300
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530301void reportError(const char* errorMsg)
George Liu83409572019-12-24 18:42:54 +0800302{
George Liu0e02c322020-01-01 09:41:51 +0800303 auto& bus = pldm::utils::DBusHandler::getBus();
Riya Dixit76f2c602024-03-28 07:34:12 -0500304 using LoggingCreate =
305 sdbusplus::client::xyz::openbmc_project::logging::Create<>;
George Liu83409572019-12-24 18:42:54 +0800306 try
307 {
George Liu83409572019-12-24 18:42:54 +0800308 using namespace sdbusplus::xyz::openbmc_project::Logging::server;
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530309 auto severity =
310 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
311 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
312 Error);
Pavithra Barithaya7b4d59a2024-02-05 09:09:30 -0600313 auto method = bus.new_method_call(LoggingCreate::default_service,
314 LoggingCreate::instance_path,
315 LoggingCreate::interface, "Create");
316
George Liu83409572019-12-24 18:42:54 +0800317 std::map<std::string, std::string> addlData{};
318 method.append(errorMsg, severity, addlData);
vkaverap@in.ibm.com5b71b862023-08-21 05:19:04 +0000319 bus.call_noreply(method, dbusTimeout);
George Liu83409572019-12-24 18:42:54 +0800320 }
321 catch (const std::exception& e)
322 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600323 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500324 "Failed to do dbus call for creating error log for '{ERRMSG}' at path '{PATH}' and interface '{INTERFACE}', error - {ERROR}",
325 "ERRMSG", errorMsg, "PATH", LoggingCreate::instance_path,
326 "INTERFACE", LoggingCreate::interface, "ERROR", e);
George Liu83409572019-12-24 18:42:54 +0800327 }
328}
329
George Liu1e44c732020-02-28 20:20:06 +0800330void DBusHandler::setDbusProperty(const DBusMapping& dBusMap,
331 const PropertyValue& value) const
332{
333 auto setDbusValue = [&dBusMap, this](const auto& variant) {
334 auto& bus = getBus();
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400335 auto service =
336 getService(dBusMap.objectPath.c_str(), dBusMap.interface.c_str());
George Liu1e44c732020-02-28 20:20:06 +0800337 auto method = bus.new_method_call(
338 service.c_str(), dBusMap.objectPath.c_str(), dbusProperties, "Set");
339 method.append(dBusMap.interface.c_str(), dBusMap.propertyName.c_str(),
340 variant);
vkaverap@in.ibm.com5b71b862023-08-21 05:19:04 +0000341 bus.call_noreply(method, dbusTimeout);
George Liu1e44c732020-02-28 20:20:06 +0800342 };
343
344 if (dBusMap.propertyType == "uint8_t")
345 {
346 std::variant<uint8_t> v = std::get<uint8_t>(value);
347 setDbusValue(v);
348 }
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600349 else if (dBusMap.propertyType == "bool")
350 {
351 std::variant<bool> v = std::get<bool>(value);
352 setDbusValue(v);
353 }
George Liu1e44c732020-02-28 20:20:06 +0800354 else if (dBusMap.propertyType == "int16_t")
355 {
356 std::variant<int16_t> v = std::get<int16_t>(value);
357 setDbusValue(v);
358 }
359 else if (dBusMap.propertyType == "uint16_t")
360 {
361 std::variant<uint16_t> v = std::get<uint16_t>(value);
362 setDbusValue(v);
363 }
364 else if (dBusMap.propertyType == "int32_t")
365 {
366 std::variant<int32_t> v = std::get<int32_t>(value);
367 setDbusValue(v);
368 }
369 else if (dBusMap.propertyType == "uint32_t")
370 {
371 std::variant<uint32_t> v = std::get<uint32_t>(value);
372 setDbusValue(v);
373 }
374 else if (dBusMap.propertyType == "int64_t")
375 {
376 std::variant<int64_t> v = std::get<int64_t>(value);
377 setDbusValue(v);
378 }
379 else if (dBusMap.propertyType == "uint64_t")
380 {
381 std::variant<uint64_t> v = std::get<uint64_t>(value);
382 setDbusValue(v);
383 }
384 else if (dBusMap.propertyType == "double")
385 {
386 std::variant<double> v = std::get<double>(value);
387 setDbusValue(v);
388 }
389 else if (dBusMap.propertyType == "string")
390 {
391 std::variant<std::string> v = std::get<std::string>(value);
392 setDbusValue(v);
393 }
394 else
395 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500396 error("Unsupported property type '{TYPE}'", "TYPE",
397 dBusMap.propertyType);
398 throw std::invalid_argument("UnSupported Dbus Type");
George Liu1e44c732020-02-28 20:20:06 +0800399 }
400}
401
John Wang9e242422020-03-05 08:37:50 +0800402PropertyValue DBusHandler::getDbusPropertyVariant(
403 const char* objPath, const char* dbusProp, const char* dbusInterface) const
404{
405 auto& bus = DBusHandler::getBus();
406 auto service = getService(objPath, dbusInterface);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400407 auto method =
408 bus.new_method_call(service.c_str(), objPath, dbusProperties, "Get");
John Wang9e242422020-03-05 08:37:50 +0800409 method.append(dbusInterface, dbusProp);
Patrick Williams75b8f462024-02-07 10:59:26 -0600410 return bus.call(method, dbusTimeout).unpack<PropertyValue>();
John Wang9e242422020-03-05 08:37:50 +0800411}
412
Riya Dixit754041d2024-02-20 06:15:49 -0600413ObjectValueTree DBusHandler::getManagedObj(const char* service,
414 const char* rootPath)
415{
416 auto& bus = DBusHandler::getBus();
417 auto method = bus.new_method_call(service, rootPath,
418 "org.freedesktop.DBus.ObjectManager",
419 "GetManagedObjects");
420 return bus.call(method).unpack<ObjectValueTree>();
421}
422
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400423PropertyMap DBusHandler::getDbusPropertiesVariant(
424 const char* serviceName, const char* objPath,
425 const char* dbusInterface) const
Gilbert Chen44524a52022-02-14 12:12:25 +0000426{
427 auto& bus = DBusHandler::getBus();
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400428 auto method =
429 bus.new_method_call(serviceName, objPath, dbusProperties, "GetAll");
Gilbert Chen44524a52022-02-14 12:12:25 +0000430 method.append(dbusInterface);
431 return bus.call(method, dbusTimeout).unpack<PropertyMap>();
432}
433
TOM JOSEPHd4d97a52020-03-23 14:36:34 +0530434PropertyValue jsonEntryToDbusVal(std::string_view type,
435 const nlohmann::json& value)
436{
437 PropertyValue propValue{};
438 if (type == "uint8_t")
439 {
440 propValue = static_cast<uint8_t>(value);
441 }
442 else if (type == "uint16_t")
443 {
444 propValue = static_cast<uint16_t>(value);
445 }
446 else if (type == "uint32_t")
447 {
448 propValue = static_cast<uint32_t>(value);
449 }
450 else if (type == "uint64_t")
451 {
452 propValue = static_cast<uint64_t>(value);
453 }
454 else if (type == "int16_t")
455 {
456 propValue = static_cast<int16_t>(value);
457 }
458 else if (type == "int32_t")
459 {
460 propValue = static_cast<int32_t>(value);
461 }
462 else if (type == "int64_t")
463 {
464 propValue = static_cast<int64_t>(value);
465 }
466 else if (type == "bool")
467 {
468 propValue = static_cast<bool>(value);
469 }
470 else if (type == "double")
471 {
472 propValue = static_cast<double>(value);
473 }
474 else if (type == "string")
475 {
476 propValue = static_cast<std::string>(value);
477 }
478 else
479 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500480 error("Unknown D-Bus property type '{TYPE}'", "TYPE", type);
TOM JOSEPHd4d97a52020-03-23 14:36:34 +0530481 }
482
483 return propValue;
484}
485
Tom Joseph250c4752020-04-15 10:32:45 +0530486uint16_t findStateEffecterId(const pldm_pdr* pdrRepo, uint16_t entityType,
487 uint16_t entityInstance, uint16_t containerId,
Sampa Misraa4a96162020-07-14 05:33:46 -0500488 uint16_t stateSetId, bool localOrRemote)
Tom Joseph250c4752020-04-15 10:32:45 +0530489{
490 uint8_t* pdrData = nullptr;
491 uint32_t pdrSize{};
492 const pldm_pdr_record* record{};
493 do
494 {
495 record = pldm_pdr_find_record_by_type(pdrRepo, PLDM_STATE_EFFECTER_PDR,
496 record, &pdrData, &pdrSize);
Sampa Misraa4a96162020-07-14 05:33:46 -0500497 if (record && (localOrRemote ^ pldm_pdr_record_is_remote(record)))
Tom Joseph250c4752020-04-15 10:32:45 +0530498 {
499 auto pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrData);
500 auto compositeEffecterCount = pdr->composite_effecter_count;
501 auto possible_states_start = pdr->possible_states;
502
503 for (auto effecters = 0x00; effecters < compositeEffecterCount;
504 effecters++)
505 {
506 auto possibleStates =
507 reinterpret_cast<state_effecter_possible_states*>(
508 possible_states_start);
509 auto setId = possibleStates->state_set_id;
510 auto possibleStateSize = possibleStates->possible_states_size;
511
512 if (entityType == pdr->entity_type &&
513 entityInstance == pdr->entity_instance &&
514 containerId == pdr->container_id && stateSetId == setId)
515 {
516 return pdr->effecter_id;
517 }
518 possible_states_start += possibleStateSize + sizeof(setId) +
519 sizeof(possibleStateSize);
520 }
521 }
522 } while (record);
523
524 return PLDM_INVALID_EFFECTER_ID;
525}
526
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800527int emitStateSensorEventSignal(uint8_t tid, uint16_t sensorId,
528 uint8_t sensorOffset, uint8_t eventState,
529 uint8_t previousEventState)
530{
531 try
532 {
533 auto& bus = DBusHandler::getBus();
534 auto msg = bus.new_signal("/xyz/openbmc_project/pldm",
535 "xyz.openbmc_project.PLDM.Event",
536 "StateSensorEvent");
537 msg.append(tid, sensorId, sensorOffset, eventState, previousEventState);
538
539 msg.signal_send();
540 }
Patrick Williams51330582021-10-06 12:48:56 -0500541 catch (const std::exception& e)
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800542 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500543 error("Failed to emit pldm event signal, error - {ERROR}", "ERROR", e);
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800544 return PLDM_ERROR;
545 }
546
547 return PLDM_SUCCESS;
548}
549
Chau Ly8fa40db2024-04-02 09:32:01 +0000550void recoverMctpEndpoint(const std::string& endpointObjPath)
551{
552 auto& bus = DBusHandler::getBus();
553 try
554 {
555 std::string service = DBusHandler().getService(endpointObjPath.c_str(),
556 MCTP_INTERFACE_CC);
557
558 auto method = bus.new_method_call(
559 service.c_str(), endpointObjPath.c_str(), MCTP_INTERFACE_CC,
560 MCTP_ENDPOINT_RECOVER_METHOD);
561 bus.call_noreply(method, dbusTimeout);
562 }
563 catch (const std::exception& e)
564 {
565 error(
566 "failed to make a D-Bus call to recover MCTP Endpoint, ERROR {ERR_EXCEP}",
567 "ERR_EXCEP", e);
568 }
569}
570
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500571uint16_t findStateSensorId(const pldm_pdr* pdrRepo, uint8_t tid,
572 uint16_t entityType, uint16_t entityInstance,
573 uint16_t containerId, uint16_t stateSetId)
574{
575 auto pdrs = findStateSensorPDR(tid, entityType, stateSetId, pdrRepo);
576 for (auto pdr : pdrs)
577 {
578 auto sensorPdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdr.data());
579 auto compositeSensorCount = sensorPdr->composite_sensor_count;
580 auto possible_states_start = sensorPdr->possible_states;
581
582 for (auto sensors = 0x00; sensors < compositeSensorCount; sensors++)
583 {
584 auto possibleStates =
585 reinterpret_cast<state_sensor_possible_states*>(
586 possible_states_start);
587 auto setId = possibleStates->state_set_id;
588 auto possibleStateSize = possibleStates->possible_states_size;
589 if (entityType == sensorPdr->entity_type &&
590 entityInstance == sensorPdr->entity_instance &&
591 stateSetId == setId && containerId == sensorPdr->container_id)
592 {
593 return sensorPdr->sensor_id;
594 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400595 possible_states_start +=
596 possibleStateSize + sizeof(setId) + sizeof(possibleStateSize);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500597 }
598 }
599 return PLDM_INVALID_EFFECTER_ID;
600}
601
Tom Josephe5268cd2021-09-07 13:04:03 +0530602void printBuffer(bool isTx, const std::vector<uint8_t>& buffer)
Sridevi Rameshae28bc72020-12-10 07:21:16 -0600603{
Manojkiran Edacd4cd452024-04-23 08:53:17 +0530604 if (buffer.empty())
Sridevi Rameshae28bc72020-12-10 07:21:16 -0600605 {
Manojkiran Edacd4cd452024-04-23 08:53:17 +0530606 return;
Sridevi Rameshae28bc72020-12-10 07:21:16 -0600607 }
Manojkiran Edacd4cd452024-04-23 08:53:17 +0530608
609 std::cout << (isTx ? "Tx: " : "Rx: ");
610
611 std::ranges::for_each(buffer, [](uint8_t byte) {
612 std::cout << std::format("{:02x} ", byte);
613 });
614
615 std::cout << std::endl;
Sridevi Rameshae28bc72020-12-10 07:21:16 -0600616}
617
Tom Joseph54922072021-06-19 02:45:46 -0700618std::string toString(const struct variable_field& var)
619{
620 if (var.ptr == nullptr || !var.length)
621 {
622 return "";
623 }
624
625 std::string str(reinterpret_cast<const char*>(var.ptr), var.length);
626 std::replace_if(
627 str.begin(), str.end(), [](const char& c) { return !isprint(c); }, ' ');
628 return str;
629}
630
George Liu872f0f62021-11-25 16:26:16 +0800631std::vector<std::string> split(std::string_view srcStr, std::string_view delim,
632 std::string_view trimStr)
633{
634 std::vector<std::string> out;
635 size_t start;
636 size_t end = 0;
637
638 while ((start = srcStr.find_first_not_of(delim, end)) != std::string::npos)
639 {
640 end = srcStr.find(delim, start);
641 std::string_view dstStr = srcStr.substr(start, end - start);
642 if (!trimStr.empty())
643 {
644 dstStr.remove_prefix(dstStr.find_first_not_of(trimStr));
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400645 dstStr.remove_suffix(
646 dstStr.size() - 1 - dstStr.find_last_not_of(trimStr));
George Liu872f0f62021-11-25 16:26:16 +0800647 }
648
649 if (!dstStr.empty())
650 {
651 out.push_back(std::string(dstStr));
652 }
653 }
654
655 return out;
656}
657
Manojkiran Edaef773052021-07-29 09:29:28 +0530658std::string getCurrentSystemTime()
659{
Manojkiran Eda09a89822024-04-24 11:02:44 +0530660 const auto zonedTime{std::chrono::zoned_time{
661 std::chrono::current_zone(), std::chrono::system_clock::now()}};
662 return std::format("{:%F %Z %T}", zonedTime);
Manojkiran Edaef773052021-07-29 09:29:28 +0530663}
664
Sridevi Ramesheefe49b2022-06-27 11:51:02 -0500665bool checkForFruPresence(const std::string& objPath)
666{
667 bool isPresent = false;
668 static constexpr auto presentInterface =
669 "xyz.openbmc_project.Inventory.Item";
670 static constexpr auto presentProperty = "Present";
671 try
672 {
673 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
674 objPath.c_str(), presentProperty, presentInterface);
675 isPresent = std::get<bool>(propVal);
676 }
677 catch (const sdbusplus::exception::SdBusError& e)
678 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500679 error("Failed to check for FRU presence at {PATH}, error - {ERROR}",
680 "PATH", objPath, "ERROR", e);
Sridevi Ramesheefe49b2022-06-27 11:51:02 -0500681 }
682 return isPresent;
683}
684
Sagar Srinivas5db6e872023-12-01 10:03:30 -0600685bool checkIfLogicalBitSet(const uint16_t& containerId)
686{
687 return !(containerId & 0x8000);
688}
689
Pavithra Barithaya5e542be2021-08-13 00:33:31 -0500690void setFruPresence(const std::string& fruObjPath, bool present)
691{
692 pldm::utils::PropertyValue value{present};
693 pldm::utils::DBusMapping dbusMapping;
694 dbusMapping.objectPath = fruObjPath;
695 dbusMapping.interface = "xyz.openbmc_project.Inventory.Item";
696 dbusMapping.propertyName = "Present";
697 dbusMapping.propertyType = "bool";
698 try
699 {
700 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
701 }
702 catch (const std::exception& e)
703 {
704 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500705 "Failed to set the present property on path '{PATH}', error - {ERROR}.",
Pavithra Barithaya5e542be2021-08-13 00:33:31 -0500706 "PATH", fruObjPath, "ERROR", e);
707 }
708}
709
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000710std::string_view trimNameForDbus(std::string& name)
711{
712 std::replace(name.begin(), name.end(), ' ', '_');
713 auto nullTerminatorPos = name.find('\0');
714 if (nullTerminatorPos != std::string::npos)
715 {
716 name.erase(nullTerminatorPos);
717 }
718 return name;
719}
Thu Nguyena34a64b2022-03-31 08:56:39 +0700720
721bool dbusPropValuesToDouble(const std::string_view& type,
722 const pldm::utils::PropertyValue& value,
723 double* doubleValue)
724{
725 if (!dbusValueNumericTypeNames.contains(type))
726 {
727 return false;
728 }
729
730 if (!doubleValue)
731 {
732 return false;
733 }
734
735 try
736 {
737 if (type == "uint8_t")
738 {
739 *doubleValue = static_cast<double>(std::get<uint8_t>(value));
740 }
741 else if (type == "int16_t")
742 {
743 *doubleValue = static_cast<double>(std::get<int16_t>(value));
744 }
745 else if (type == "uint16_t")
746 {
747 *doubleValue = static_cast<double>(std::get<uint16_t>(value));
748 }
749 else if (type == "int32_t")
750 {
751 *doubleValue = static_cast<double>(std::get<int32_t>(value));
752 }
753 else if (type == "uint32_t")
754 {
755 *doubleValue = static_cast<double>(std::get<uint32_t>(value));
756 }
757 else if (type == "int64_t")
758 {
759 *doubleValue = static_cast<double>(std::get<int64_t>(value));
760 }
761 else if (type == "uint64_t")
762 {
763 *doubleValue = static_cast<double>(std::get<uint64_t>(value));
764 }
765 else if (type == "double")
766 {
767 *doubleValue = static_cast<double>(std::get<double>(value));
768 }
769 else
770 {
771 return false;
772 }
773 }
774 catch (const std::exception& e)
775 {
776 return false;
777 }
778
779 return true;
780}
Dung Caob6d39432024-06-05 03:46:47 +0000781
Patrick Williams366507c2025-02-03 14:28:01 -0500782std::optional<std::string> fruFieldValuestring(const uint8_t* value,
783 const uint8_t& length)
Dung Caob6d39432024-06-05 03:46:47 +0000784{
785 if (!value || !length)
786 {
787 lg2::error("Fru data to string invalid data.");
788 return std::nullopt;
789 }
790
791 return std::string(reinterpret_cast<const char*>(value), length);
792}
793
794std::optional<uint32_t> fruFieldParserU32(const uint8_t* value,
795 const uint8_t& length)
796{
797 if (!value || length != sizeof(uint32_t))
798 {
799 lg2::error("Fru data to u32 invalid data.");
800 return std::nullopt;
801 }
802
803 uint32_t ret;
804 std::memcpy(&ret, value, length);
805 return ret;
806}
807
George Liu83409572019-12-24 18:42:54 +0800808} // namespace utils
809} // namespace pldm