xref: /openbmc/pldm/common/utils.hpp (revision 9c1455c067c2f11b85d52ce217a795db6857507e)
1 #pragma once
2 
3 #include "types.hpp"
4 
5 #include <libpldm/base.h>
6 #include <libpldm/bios.h>
7 #include <libpldm/entity.h>
8 #include <libpldm/pdr.h>
9 #include <libpldm/platform.h>
10 #include <systemd/sd-bus.h>
11 #include <unistd.h>
12 
13 #include <nlohmann/json.hpp>
14 #include <phosphor-logging/lg2.hpp>
15 #include <sdbusplus/server.hpp>
16 #include <xyz/openbmc_project/BIOSConfig/Manager/common.hpp>
17 #include <xyz/openbmc_project/Inventory/Manager/client.hpp>
18 #include <xyz/openbmc_project/Logging/Entry/server.hpp>
19 #include <xyz/openbmc_project/ObjectMapper/client.hpp>
20 
21 #include <cstdint>
22 #include <deque>
23 #include <exception>
24 #include <filesystem>
25 #include <iostream>
26 #include <map>
27 #include <string>
28 #include <variant>
29 #include <vector>
30 
31 constexpr uint64_t dbusTimeout =
32     std::chrono::duration_cast<std::chrono::microseconds>(
33         std::chrono::seconds(DBUS_TIMEOUT))
34         .count();
35 
36 PHOSPHOR_LOG2_USING;
37 
38 namespace pldm
39 {
40 namespace utils
41 {
42 
43 enum class Level
44 {
45     WARNING,
46     CRITICAL,
47     PERFORMANCELOSS,
48     SOFTSHUTDOWN,
49     HARDSHUTDOWN,
50     ERROR
51 };
52 enum class Direction
53 {
54     HIGH,
55     LOW,
56     ERROR
57 };
58 
59 const std::set<std::string_view> dbusValueTypeNames = {
60     "bool",    "uint8_t",  "int16_t",         "uint16_t",
61     "int32_t", "uint32_t", "int64_t",         "uint64_t",
62     "double",  "string",   "vector<uint8_t>", "vector<string>"};
63 const std::set<std::string_view> dbusValueNumericTypeNames = {
64     "uint8_t",  "int16_t", "uint16_t", "int32_t",
65     "uint32_t", "int64_t", "uint64_t", "double"};
66 
67 namespace fs = std::filesystem;
68 using Json = nlohmann::json;
69 constexpr bool Tx = true;
70 constexpr bool Rx = false;
71 using ObjectMapper = sdbusplus::client::xyz::openbmc_project::ObjectMapper<>;
72 using inventoryManager =
73     sdbusplus::client::xyz::openbmc_project::inventory::Manager<>;
74 
75 constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
76 constexpr auto mapperService = ObjectMapper::default_service;
77 constexpr auto inventoryPath = "/xyz/openbmc_project/inventory";
78 
79 /** @struct CustomFD
80  *
81  *  RAII wrapper for file descriptor.
82  */
83 struct CustomFD
84 {
85     CustomFD(const CustomFD&) = delete;
86     CustomFD& operator=(const CustomFD&) = delete;
87     CustomFD(CustomFD&&) = delete;
88     CustomFD& operator=(CustomFD&&) = delete;
89 
CustomFDpldm::utils::CustomFD90     CustomFD(int fd) : fd(fd) {}
91 
~CustomFDpldm::utils::CustomFD92     ~CustomFD()
93     {
94         if (fd >= 0)
95         {
96             close(fd);
97         }
98     }
99 
operator ()pldm::utils::CustomFD100     int operator()() const
101     {
102         return fd;
103     }
104 
105   private:
106     int fd = -1;
107 };
108 
109 /** @brief Calculate the pad for PLDM data
110  *
111  *  @param[in] data - Length of the data
112  *  @return - uint8_t - number of pad bytes
113  */
114 uint8_t getNumPadBytes(uint32_t data);
115 
116 /** @brief Convert uint64 to date
117  *
118  *  @param[in] data - time date of uint64
119  *  @param[out] year - year number in dec
120  *  @param[out] month - month number in dec
121  *  @param[out] day - day of the month in dec
122  *  @param[out] hour - number of hours in dec
123  *  @param[out] min - number of minutes in dec
124  *  @param[out] sec - number of seconds in dec
125  *  @return true if decode success, false if decode failed
126  */
127 bool uintToDate(uint64_t data, uint16_t* year, uint8_t* month, uint8_t* day,
128                 uint8_t* hour, uint8_t* min, uint8_t* sec);
129 
130 /** @brief Convert effecter data to structure of set_effecter_state_field
131  *
132  *  @param[in] effecterData - the date of effecter
133  *  @param[in] effecterCount - the number of individual sets of effecter
134  *                              information
135  *  @return[out] parse success and get a valid set_effecter_state_field
136  *               structure, return nullopt means parse failed
137  */
138 std::optional<std::vector<set_effecter_state_field>> parseEffecterData(
139     const std::vector<uint8_t>& effecterData, uint8_t effecterCount);
140 
141 /**
142  *  @brief creates an error log
143  *  @param[in] errorMsg - the error message
144  */
145 void reportError(const char* errorMsg);
146 
147 /** @brief Convert any Decimal number to BCD
148  *
149  *  @tparam[in] decimal - Decimal number
150  *  @return Corresponding BCD number
151  */
152 template <typename T>
decimalToBcd(T decimal)153 T decimalToBcd(T decimal)
154 {
155     T bcd = 0;
156     T rem = 0;
157     auto cnt = 0;
158 
159     while (decimal)
160     {
161         rem = decimal % 10;
162         bcd = bcd + (rem << cnt);
163         decimal = decimal / 10;
164         cnt += 4;
165     }
166 
167     return bcd;
168 }
169 
170 struct DBusMapping
171 {
172     std::string objectPath;   //!< D-Bus object path
173     std::string interface;    //!< D-Bus interface
174     std::string propertyName; //!< D-Bus property name
175     std::string propertyType; //!< D-Bus property type
176 };
177 
178 using PropertyValue =
179     std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
180                  uint64_t, double, std::string, std::vector<uint8_t>,
181                  std::vector<uint64_t>, std::vector<std::string>>;
182 using DbusProp = std::string;
183 using DbusChangedProps = std::map<DbusProp, PropertyValue>;
184 using DBusInterfaceAdded = std::vector<
185     std::pair<pldm::dbus::Interface,
186               std::vector<std::pair<pldm::dbus::Property,
187                                     std::variant<pldm::dbus::Property>>>>>;
188 
189 using ObjectPath = std::string;
190 using EntityName = std::string;
191 using Entities = std::vector<pldm_entity_node*>;
192 using EntityAssociations = std::vector<Entities>;
193 using ObjectPathMaps = std::map<fs::path, pldm_entity_node*>;
194 using EntityMaps = std::map<pldm::pdr::EntityType, EntityName>;
195 
196 using ServiceName = std::string;
197 using Interfaces = std::vector<std::string>;
198 using MapperServiceMap = std::vector<std::pair<ServiceName, Interfaces>>;
199 using GetSubTreeResponse = std::vector<std::pair<ObjectPath, MapperServiceMap>>;
200 using GetSubTreePathsResponse = std::vector<std::string>;
201 using GetAssociatedSubTreeResponse =
202     std::map<std::string, std::map<std::string, std::vector<std::string>>>;
203 using GetAncestorsResponse =
204     std::vector<std::pair<ObjectPath, MapperServiceMap>>;
205 using PropertyMap = std::map<std::string, PropertyValue>;
206 using InterfaceMap = std::map<std::string, PropertyMap>;
207 using ObjectValueTree = std::map<sdbusplus::message::object_path, InterfaceMap>;
208 using AttributeName = std::string;
209 using AttributeType = std::string;
210 using AttributeValue = std::variant<std::string, int64_t>;
211 using PendingAttributesList = std::vector<
212     std::pair<AttributeName, std::tuple<AttributeType, AttributeValue>>>;
213 
214 using SensorPDR = std::vector<uint8_t>;
215 using SensorPDRs = std::vector<SensorPDR>;
216 using EffecterPDR = std::vector<uint8_t>;
217 using EffecterPDRs = std::vector<EffecterPDR>;
218 
219 constexpr auto EnumAttribute =
220     "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Enumeration";
221 
222 /**
223  * @brief The interface for DBusHandler
224  */
225 class DBusHandlerInterface
226 {
227   public:
228     virtual ~DBusHandlerInterface() = default;
229 
230     virtual std::string getService(const char* path,
231                                    const char* interface) const = 0;
232     virtual GetSubTreeResponse getSubtree(
233         const std::string& path, int depth,
234         const std::vector<std::string>& ifaceList) const = 0;
235 
236     virtual GetSubTreePathsResponse getSubTreePaths(
237         const std::string& objectPath, int depth,
238         const std::vector<std::string>& ifaceList) const = 0;
239 
240     virtual GetAncestorsResponse getAncestors(
241         const std::string& path,
242         const std::vector<std::string>& ifaceList) const = 0;
243 
244     virtual void setDbusProperty(const DBusMapping& dBusMap,
245                                  const PropertyValue& value) const = 0;
246 
247     virtual PropertyValue getDbusPropertyVariant(
248         const char* objPath, const char* dbusProp,
249         const char* dbusInterface) const = 0;
250 
251     virtual PropertyMap getDbusPropertiesVariant(
252         const char* serviceName, const char* objPath,
253         const char* dbusInterface) const = 0;
254 
255     virtual GetAssociatedSubTreeResponse getAssociatedSubTree(
256         const sdbusplus::message::object_path& objectPath,
257         const sdbusplus::message::object_path& subtree, int depth,
258         const std::vector<std::string>& ifaceList) const = 0;
259 };
260 
261 /**
262  *  @class DBusHandler
263  *
264  *  Wrapper class to handle the D-Bus calls
265  *
266  *  This class contains the APIs to handle the D-Bus calls
267  *  to cater the request from pldm requester.
268  *  A class is created to mock the apis in the test cases
269  */
270 class DBusHandler : public DBusHandlerInterface
271 {
272   public:
273     /** @brief Get the bus connection. */
getBus()274     static auto& getBus()
275     {
276         static auto bus = sdbusplus::bus::new_default();
277         return bus;
278     }
279 
280     /**
281      *  @brief Get the DBUS Service name for the input dbus path
282      *
283      *  @param[in] path - DBUS object path
284      *  @param[in] interface - DBUS Interface
285      *
286      *  @return std::string - the dbus service name
287      *
288      *  @throw sdbusplus::exception_t when it fails
289      */
290     std::string getService(const char* path,
291                            const char* interface) const override;
292 
293     /**
294      *  @brief Get the Subtree response from the mapper
295      *
296      *  @param[in] path - DBUS object path
297      *  @param[in] depth - Search depth
298      *  @param[in] ifaceList - list of the interface that are being
299      *                         queried from the mapper
300      *
301      *  @return GetSubTreeResponse - the mapper subtree response
302      *
303      *  @throw sdbusplus::exception_t when it fails
304      */
305     GetSubTreeResponse getSubtree(
306         const std::string& path, int depth,
307         const std::vector<std::string>& ifaceList) const override;
308 
309     /** @brief Get Subtree path response from the mapper
310      *
311      *  @param[in] path - DBUS object path
312      *  @param[in] depth - Search depth
313      *  @param[in] ifaceList - list of the interface that are being
314      *                         queried from the mapper
315      *
316      *  @return std::vector<std::string> vector of subtree paths
317      */
318     GetSubTreePathsResponse getSubTreePaths(
319         const std::string& objectPath, int depth,
320         const std::vector<std::string>& ifaceList) const override;
321 
322     /**
323      *  @brief Get the Ancestors response from the mapper
324      *
325      *  @param[in] path - D-Bus object path
326      *  @param[in] ifaceList - an optional list of interfaces to constrain the
327      *                         search to queried from the mapper
328      *
329      *  @return GetAncestorsResponse - the mapper GetAncestors response
330      *
331      *  @throw sdbusplus::exception_t when it fails
332      */
333     GetAncestorsResponse getAncestors(
334         const std::string& path,
335         const std::vector<std::string>& ifaceList) const override;
336 
337     /** @brief Get property(type: variant) from the requested dbus
338      *
339      *  @param[in] objPath - The Dbus object path
340      *  @param[in] dbusProp - The property name to get
341      *  @param[in] dbusInterface - The Dbus interface
342      *
343      *  @return The value of the property(type: variant)
344      *
345      *  @throw sdbusplus::exception_t when it fails
346      */
347     PropertyValue getDbusPropertyVariant(
348         const char* objPath, const char* dbusProp,
349         const char* dbusInterface) const override;
350 
351     /** @brief Get All properties(type: variant) from the requested dbus
352      *
353      *  @param[in] serviceName - The Dbus service name
354      *  @param[in] objPath - The Dbus object path
355      *  @param[in] dbusInterface - The Dbus interface
356      *
357      *  @return The values of the properties(type: variant)
358      *
359      *  @throw sdbusplus::exception_t when it fails
360      */
361     PropertyMap getDbusPropertiesVariant(
362         const char* serviceName, const char* objPath,
363         const char* dbusInterface) const override;
364 
365     /** @brief The template function to get property from the requested dbus
366      *         path
367      *
368      *  @tparam Property - Excepted type of the property on dbus
369      *
370      *  @param[in] objPath - The Dbus object path
371      *  @param[in] dbusProp - The property name to get
372      *  @param[in] dbusInterface - The Dbus interface
373      *
374      *  @return The value of the property
375      *
376      *  @throw sdbusplus::exception_t when dbus request fails
377      *         std::bad_variant_access when \p Property and property on dbus do
378      *         not match
379      */
380     template <typename Property>
getDbusProperty(const char * objPath,const char * dbusProp,const char * dbusInterface)381     auto getDbusProperty(const char* objPath, const char* dbusProp,
382                          const char* dbusInterface)
383     {
384         auto VariantValue =
385             getDbusPropertyVariant(objPath, dbusProp, dbusInterface);
386         return std::get<Property>(VariantValue);
387     }
388 
389     /** @brief Get the associated subtree from the mapper
390      *
391      * @param[in] path - The D-Bus object path
392      *
393      * @param[in] interface - The D-Bus interface
394      *
395      * @return GetAssociatedSubtreeResponse - The associated subtree
396      */
397     GetAssociatedSubTreeResponse getAssociatedSubTree(
398         const sdbusplus::message::object_path& objectPath,
399         const sdbusplus::message::object_path& subtree, int depth,
400         const std::vector<std::string>& ifaceList) const override;
401 
402     /** @brief Set Dbus property
403      *
404      *  @param[in] dBusMap - Object path, property name, interface and property
405      *                       type for the D-Bus object
406      *  @param[in] value - The value to be set
407      *
408      *  @throw sdbusplus::exception_t when it fails
409      */
410     void setDbusProperty(const DBusMapping& dBusMap,
411                          const PropertyValue& value) const override;
412 
413     /** @brief This function retrieves the properties of an object managed
414      *         by the specified D-Bus service located at the given object path.
415      *
416      *  @param[in] service - The D-Bus service providing the managed object
417      *  @param[in] value - The object path of the managed object
418      *
419      *  @return A hierarchical structure representing the properties of the
420      *          managed object.
421      *  @throw sdbusplus::exception_t when it fails
422      */
423     static ObjectValueTree getManagedObj(const char* service, const char* path);
424 
425     /** @brief Retrieve the inventory objects managed by a specified class.
426      *         The retrieved inventory objects are cached statically
427      *         and returned upon subsequent calls to this function.
428      *
429      *  @tparam ClassType - The class type that manages the inventory objects.
430      *
431      *  @return A reference to the cached inventory objects.
432      */
433     template <typename ClassType>
getInventoryObjects()434     static auto& getInventoryObjects()
435     {
436         static ObjectValueTree object = ClassType::getManagedObj(
437             inventoryManager::interface, inventoryPath);
438         return object;
439     }
440 };
441 
442 /** @brief Fetch parent D-Bus object based on pathname
443  *
444  *  @param[in] dbusObj - child D-Bus object
445  *
446  *  @return std::string - the parent D-Bus object path
447  */
findParent(const std::string & dbusObj)448 inline std::string findParent(const std::string& dbusObj)
449 {
450     fs::path p(dbusObj);
451     return p.parent_path().string();
452 }
453 
454 /** @brief Read (static) MCTP EID of host firmware from a file
455  *
456  *  @return uint8_t - MCTP EID
457  */
458 uint8_t readHostEID();
459 
460 /** @brief Validate the MCTP EID of MCTP endpoint
461  *         In `Table 2 - Special endpoint IDs` of DSP0236. EID 0 is NULL_EID.
462  *         EID from 1 to 7 is reserved EID. EID 0xFF is broadcast EID.
463  *         Those are invalid EID of one MCTP Endpoint.
464  *
465  * @param[in] eid - MCTP EID
466  *
467  * @return true if the MCTP EID is valid otherwise return false.
468  */
469 bool isValidEID(eid mctpEid);
470 
471 /** @brief Convert a value in the JSON to a D-Bus property value
472  *
473  *  @param[in] type - type of the D-Bus property
474  *  @param[in] value - value in the JSON file
475  *
476  *  @return PropertyValue - the D-Bus property value
477  */
478 PropertyValue jsonEntryToDbusVal(std::string_view type,
479                                  const nlohmann::json& value);
480 
481 /** @brief Find State Effecter PDR
482  *  @param[in] tid - PLDM terminus ID.
483  *  @param[in] entityID - entity that can be associated with PLDM State set.
484  *  @param[in] stateSetId - value that identifies PLDM State set.
485  *  @param[in] repo - pointer to BMC's primary PDR repo.
486  *  @return array[array[uint8_t]] - StateEffecterPDRs
487  */
488 std::vector<std::vector<uint8_t>> findStateEffecterPDR(
489     uint8_t tid, uint16_t entityID, uint16_t stateSetId, const pldm_pdr* repo);
490 /** @brief Find State Sensor PDR
491  *  @param[in] tid - PLDM terminus ID.
492  *  @param[in] entityID - entity that can be associated with PLDM State set.
493  *  @param[in] stateSetId - value that identifies PLDM State set.
494  *  @param[in] repo - pointer to BMC's primary PDR repo.
495  *  @return array[array[uint8_t]] - StateSensorPDRs
496  */
497 std::vector<std::vector<uint8_t>> findStateSensorPDR(
498     uint8_t tid, uint16_t entityID, uint16_t stateSetId, const pldm_pdr* repo);
499 
500 /** @brief Find sensor id from a state sensor PDR
501  *
502  *  @param[in] pdrRepo - PDR repository
503  *  @param[in] tid - terminus id
504  *  @param[in] entityType - entity type
505  *  @param[in] entityInstance - entity instance number
506  *  @param[in] containerId - container id
507  *  @param[in] stateSetId - state set id
508  *
509  *  @return uint16_t - the sensor id
510  */
511 uint16_t findStateSensorId(const pldm_pdr* pdrRepo, uint8_t tid,
512                            uint16_t entityType, uint16_t entityInstance,
513                            uint16_t containerId, uint16_t stateSetId);
514 
515 /** @brief Find effecter id from a state effecter pdr
516  *  @param[in] pdrRepo - PDR repository
517  *  @param[in] entityType - entity type
518  *  @param[in] entityInstance - entity instance number
519  *  @param[in] containerId - container id
520  *  @param[in] stateSetId - state set id
521  *  @param[in] localOrRemote - true for checking local repo and false for remote
522  *                             repo
523  *
524  *  @return uint16_t - the effecter id
525  */
526 uint16_t findStateEffecterId(const pldm_pdr* pdrRepo, uint16_t entityType,
527                              uint16_t entityInstance, uint16_t containerId,
528                              uint16_t stateSetId, bool localOrRemote);
529 
530 /** @brief Method to find all state sensor PDRs by type
531  *
532  *  @param[in] entityType - the entity type
533  *  @param[in] repo - opaque pointer acting as a PDR repo handle
534  *
535  *  @return vector of vector of all state sensor PDRs
536  */
537 SensorPDRs getStateSensorPDRsByType(uint16_t entityType, const pldm_pdr* repo);
538 
539 /** @brief method to find sensor IDs based on the pldm_entity
540  *
541  *  @param[in] pdrRepo - opaque pointer acting as a PDR repo handle
542  *  @param[in] entityType - the entity type
543  *  @param[in] entityInstance - the entity instance number
544  *  @param[in] containerId - the container ID
545  *
546  *  @return vector of all sensor IDs
547  */
548 std::vector<pldm::pdr::SensorID> findSensorIds(
549     const pldm_pdr* pdrRepo, uint16_t entityType, uint16_t entityInstance,
550     uint16_t containerId);
551 
552 /** @brief Method to find all state effecter PDRs by type
553  *
554  *  @param[in] entityType - the entity type
555  *  @param[in] repo - opaque pointer acting as a PDR repo handle
556  *
557  *  @return vector of vector of all state effecter PDRs
558  */
559 EffecterPDRs getStateEffecterPDRsByType(uint16_t entityType,
560                                         const pldm_pdr* repo);
561 
562 /** @brief method to find effecter IDs based on the pldm_entity
563  *
564  *  @param[in] pdrRepo - opaque pointer acting as a PDR repo handle
565  *  @param[in] entityType - the entity type
566  *  @param[in] entityInstance - the entity instance number
567  *  @param[in] containerId - the container ID
568  *
569  *  @return vector of all effecter IDs
570  */
571 std::vector<pldm::pdr::EffecterID> findEffecterIds(
572     const pldm_pdr* pdrRepo, uint16_t entityType, uint16_t entityInstance,
573     uint16_t containerId);
574 
575 /** @brief Emit the sensor event signal
576  *
577  *	@param[in] tid - the terminus id
578  *  @param[in] sensorId - sensorID value of the sensor
579  *  @param[in] sensorOffset - Identifies which state sensor within a
580  * composite state sensor the event is being returned for
581  *  @param[in] eventState - The event state value from the state change that
582  * triggered the event message
583  *  @param[in] previousEventState - The event state value for the state from
584  * which the present event state was entered.
585  *  @return PLDM completion code
586  */
587 int emitStateSensorEventSignal(uint8_t tid, uint16_t sensorId,
588                                uint8_t sensorOffset, uint8_t eventState,
589                                uint8_t previousEventState);
590 
591 /**
592  *  @brief call Recover() method to recover an MCTP Endpoint
593  *  @param[in] MCTP Endpoint's object path
594  */
595 void recoverMctpEndpoint(const std::string& endpointObjPath);
596 
597 /** @brief Print the buffer
598  *
599  *  @param[in]  isTx - True if the buffer is an outgoing PLDM message, false if
600                        the buffer is an incoming PLDM message
601  *  @param[in]  buffer - Buffer to print
602  *
603  *  @return - None
604  */
605 void printBuffer(bool isTx, const std::vector<uint8_t>& buffer);
606 
607 /** @brief Convert the buffer to std::string
608  *
609  *  If there are characters that are not printable characters, it is replaced
610  *  with space(0x20).
611  *
612  *  @param[in] var - pointer to data and length of the data
613  *
614  *  @return std::string equivalent of variable field
615  */
616 std::string toString(const struct variable_field& var);
617 
618 /** @brief Split strings according to special identifiers
619  *
620  *  We can split the string according to the custom identifier(';', ',', '&' or
621  *  others) and store it to vector.
622  *
623  *  @param[in] srcStr       - The string to be split
624  *  @param[in] delim        - The custom identifier
625  *  @param[in] trimStr      - The first and last string to be trimmed
626  *
627  *  @return std::vector<std::string> Vectors are used to store strings
628  */
629 std::vector<std::string> split(std::string_view srcStr, std::string_view delim,
630                                std::string_view trimStr = "");
631 /** @brief Get the current system time in readable format
632  *
633  *  @return - std::string equivalent of the system time
634  */
635 std::string getCurrentSystemTime();
636 
637 /** @brief checks if the FRU is actually present.
638  *  @param[in] objPath - FRU object path.
639  *
640  *  @return bool to indicate presence or absence of FRU.
641  */
642 bool checkForFruPresence(const std::string& objPath);
643 
644 /** @brief Method to check if the logical bit is set
645  *
646  *  @param[containerId] - container id of the entity
647  *
648  *  @return true or false based on the logic bit set
649  */
650 bool checkIfLogicalBitSet(const uint16_t& containerId);
651 
652 /** @brief setting the present property
653  *
654  *  @param[in] objPath - the object path of the fru
655  *  @param[in] present - status to set either true/false
656  */
657 void setFruPresence(const std::string& fruObjPath, bool present);
658 
659 /** @brief Trim `\0` in string and replace ` ` by `_` to use name in D-Bus
660  *         object path
661  *
662  *  @param[in] name - the input string
663  *
664  *  @return the result string
665  */
666 std::string_view trimNameForDbus(std::string& name);
667 
668 /** @brief Convert the number type D-Bus Value to the double
669  *
670  *  @param[in] type - string type should in dbusValueNumericTypeNames list
671  *  @param[in] value - DBus PropertyValue variant
672  *  @param[out] doubleValue - response value
673  *
674  *  @return true if data type is corrected and converting is successful
675  *          otherwise return false.
676  */
677 bool dbusPropValuesToDouble(const std::string_view& type,
678                             const pldm::utils::PropertyValue& value,
679                             double* doubleValue);
680 
681 /** @brief Convert the Fru String bytes from PLDM Fru to std::string
682  *
683  *  @param[in] value - the Fru String bytes
684  *  @param[in] length - Number of bytes
685  *
686  *  @return Fru string or nullopt.
687  */
688 std::optional<std::string> fruFieldValuestring(const uint8_t* value,
689                                                const uint8_t& length);
690 
691 /** @brief Convert the Fru Uint32 raw data from PLDM Fru to uint32_t
692  *
693  *  @param[in] value - the Fru uint32 raw data
694  *  @param[in] length - Number of bytes
695  *
696  *  @return Fru uint32_t or nullopt.
697  */
698 std::optional<uint32_t> fruFieldParserU32(const uint8_t* value,
699                                           const uint8_t& length);
700 
701 /**
702  * @brief Get a random ID for firmware inventory entry
703  * @return Random ID as long integer
704  */
705 long int generateSwId();
706 
707 constexpr auto biosConfigPath = "/xyz/openbmc_project/bios_config/manager";
708 
709 /** @brief Method to get the value from a bios attribute
710  *
711  *  @param[in] dbusAttrName - the bios attribute name from
712  *             which the value must be retrieved
713  *
714  *  @return the attribute value
715  */
716 template <typename T>
getBiosAttrValue(const std::string & dbusAttrName)717 std::optional<T> getBiosAttrValue(const std::string& dbusAttrName)
718 {
719     using BIOSConfigManager =
720         sdbusplus::common::xyz::openbmc_project::bios_config::Manager;
721 
722     std::string var1;
723     std::variant<std::string, int64_t> var2, var3;
724     auto& bus = DBusHandler::getBus();
725     try
726     {
727         auto service = pldm::utils::DBusHandler().getService(
728             biosConfigPath, BIOSConfigManager::interface);
729         auto method = bus.new_method_call(
730             service.c_str(), biosConfigPath, BIOSConfigManager::interface,
731             BIOSConfigManager::method_names::get_attribute);
732         method.append(dbusAttrName);
733         auto reply = bus.call(method, dbusTimeout);
734         reply.read(var1, var2, var3);
735         if (auto ptr = std::get_if<T>(&var2))
736         {
737             return *ptr;
738         }
739     }
740     catch (const sdbusplus::exception::SdBusError& e)
741     {
742         info("Error getting the bios attribute {BIOS_ATTR}: {ERR_EXCEP}",
743              "BIOS_ATTR", dbusAttrName, "ERR_EXCEP", e);
744     }
745 
746     return std::nullopt;
747 }
748 
749 /** @brief Method to set the specified bios attribute with
750  *         specified value
751  *
752  *  @param[in] PendingAttributesList - the list of bios attribute and values
753  *             to be set
754  */
755 void setBiosAttr(const PendingAttributesList& biosAttrList);
756 
757 } // namespace utils
758 } // namespace pldm
759