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