blob: f49429167be825e25f1251dee0da6a6ff6ecadbb [file] [log] [blame]
Sampa Misra032bd502019-03-06 05:03:22 -06001#pragma once
2
3#include <stdint.h>
4#include <systemd/sd-bus.h>
Jinu Joy Thomasf666db12019-05-29 05:22:31 -05005#include <unistd.h>
Sampa Misra032bd502019-03-06 05:03:22 -06006
Sampa Misraa2fa0702019-05-31 01:28:55 -05007#include <exception>
John Wang92b3c972019-10-17 11:06:41 +08008#include <phosphor-logging/log.hpp>
Sampa Misra032bd502019-03-06 05:03:22 -06009#include <sdbusplus/server.hpp>
10#include <string>
Sampa Misraa2fa0702019-05-31 01:28:55 -050011#include <variant>
12#include <vector>
13
14#include "libpldm/base.h"
Sampa Misra032bd502019-03-06 05:03:22 -060015
16namespace pldm
17{
18namespace responder
19{
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050020namespace utils
21{
22
23/** @struct CustomFD
24 *
25 * RAII wrapper for file descriptor.
26 */
27struct CustomFD
28{
29 CustomFD(const CustomFD&) = delete;
30 CustomFD& operator=(const CustomFD&) = delete;
31 CustomFD(CustomFD&&) = delete;
32 CustomFD& operator=(CustomFD&&) = delete;
33
34 CustomFD(int fd) : fd(fd)
35 {
36 }
37
38 ~CustomFD()
39 {
40 if (fd >= 0)
41 {
42 close(fd);
43 }
44 }
45
46 int operator()() const
47 {
48 return fd;
49 }
50
51 private:
52 int fd = -1;
53};
54
Sampa Misrab37be312019-07-03 02:26:41 -050055/** @brief Calculate the pad for PLDM data
56 *
57 * @param[in] data - Length of the data
58 * @return - uint8_t - number of pad bytes
59 */
60uint8_t getNumPadBytes(uint32_t data);
61
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050062} // namespace utils
Sampa Misra032bd502019-03-06 05:03:22 -060063
64/**
65 * @brief Get the DBUS Service name for the input dbus path
66 * @param[in] bus - DBUS Bus Object
67 * @param[in] path - DBUS object path
68 * @param[in] interface - DBUS Interface
69 * @return std::string - the dbus service name
70 */
71std::string getService(sdbusplus::bus::bus& bus, const std::string& path,
72 const std::string& interface);
73
74/** @brief Convert any Decimal number to BCD
75 *
76 * @tparam[in] decimal - Decimal number
77 * @return Corresponding BCD number
78 */
79template <typename T>
80T decimalToBcd(T decimal)
81{
82 T bcd = 0;
83 T rem = 0;
84 auto cnt = 0;
85
86 while (decimal)
87 {
88 rem = decimal % 10;
89 bcd = bcd + (rem << cnt);
90 decimal = decimal / 10;
91 cnt += 4;
92 }
93
94 return bcd;
95}
96
Sampa Misraa2fa0702019-05-31 01:28:55 -050097constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
98
99/**
100 * @class DBusHandler
101 *
102 * Wrapper class to handle the D-Bus calls
103 *
104 * This class contains the APIs to handle the D-Bus calls
105 * to cater the request from pldm requester.
106 * A class is created to mock the apis in the test cases
107 */
108class DBusHandler
109{
110 public:
111 /** @brief API to set a D-Bus property
112 *
113 * @param[in] objPath - Object path for the D-Bus object
114 * @param[in] dbusProp - The D-Bus property
115 * @param[in] dbusInterface - The D-Bus interface
116 * @param[in] value - The value to be set
117 * failure
118 */
119 template <typename T>
120 void setDbusProperty(const char* objPath, const char* dbusProp,
121 const char* dbusInterface,
122 const std::variant<T>& value) const
123 {
124 auto bus = sdbusplus::bus::new_default();
125 auto service = getService(bus, objPath, dbusInterface);
126 auto method = bus.new_method_call(service.c_str(), objPath,
127 dbusProperties, "Set");
128 method.append(dbusInterface, dbusProp, value);
129 bus.call_noreply(method);
130 }
John Wang92b3c972019-10-17 11:06:41 +0800131
132 template <typename Variant>
133 auto getDbusPropertyVariant(const char* objPath, const char* dbusProp,
134 const char* dbusInterface)
135 {
136 using namespace phosphor::logging;
137 Variant value;
138 auto bus = sdbusplus::bus::new_default();
139 auto service = getService(bus, objPath, dbusInterface);
140 auto method = bus.new_method_call(service.c_str(), objPath,
141 dbusProperties, "Get");
142 method.append(dbusInterface, dbusProp);
143 try
144 {
145 auto reply = bus.call(method);
146 reply.read(value);
147 }
148 catch (const sdbusplus::exception::SdBusError& e)
149 {
150 log<level::ERR>("dbus call expection", entry("OBJPATH=%s", objPath),
151 entry("INTERFACE=%s", dbusInterface),
152 entry("PROPERTY=%s", dbusProp),
153 entry("EXPECTION=%s", e.what()));
154 }
155 return value;
156 }
157
158 template <typename Property>
159 auto getDbusProperty(const char* objPath, const char* dbusProp,
160 const char* dbusInterface)
161 {
162 auto VariantValue = getDbusPropertyVariant<std::variant<Property>>(
163 objPath, dbusProp, dbusInterface);
164 return std::get<Property>(VariantValue);
165 }
Sampa Misraa2fa0702019-05-31 01:28:55 -0500166};
167
Sampa Misra032bd502019-03-06 05:03:22 -0600168} // namespace responder
169} // namespace pldm