blob: 453f6d940cd0b404fec5c3548861efac61c60c56 [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>
Sampa Misraaa8ae722019-12-12 03:20:40 -06008#include <iostream>
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>
Sampa Misraaa8ae722019-12-12 03:20:40 -060013#include <xyz/openbmc_project/Logging/Entry/server.hpp>
Sampa Misraa2fa0702019-05-31 01:28:55 -050014
15#include "libpldm/base.h"
Sampa Misra032bd502019-03-06 05:03:22 -060016
17namespace pldm
18{
19namespace responder
20{
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050021namespace utils
22{
23
24/** @struct CustomFD
25 *
26 * RAII wrapper for file descriptor.
27 */
28struct CustomFD
29{
30 CustomFD(const CustomFD&) = delete;
31 CustomFD& operator=(const CustomFD&) = delete;
32 CustomFD(CustomFD&&) = delete;
33 CustomFD& operator=(CustomFD&&) = delete;
34
35 CustomFD(int fd) : fd(fd)
36 {
37 }
38
39 ~CustomFD()
40 {
41 if (fd >= 0)
42 {
43 close(fd);
44 }
45 }
46
47 int operator()() const
48 {
49 return fd;
50 }
51
52 private:
53 int fd = -1;
54};
55
Sampa Misrab37be312019-07-03 02:26:41 -050056/** @brief Calculate the pad for PLDM data
57 *
58 * @param[in] data - Length of the data
59 * @return - uint8_t - number of pad bytes
60 */
61uint8_t getNumPadBytes(uint32_t data);
62
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050063} // namespace utils
Sampa Misra032bd502019-03-06 05:03:22 -060064
65/**
66 * @brief Get the DBUS Service name for the input dbus path
67 * @param[in] bus - DBUS Bus Object
68 * @param[in] path - DBUS object path
69 * @param[in] interface - DBUS Interface
70 * @return std::string - the dbus service name
71 */
72std::string getService(sdbusplus::bus::bus& bus, const std::string& path,
73 const std::string& interface);
74
Sampa Misraaa8ae722019-12-12 03:20:40 -060075/**
76 * @brief creates an error log
77 * @param[in] errorMsg - the error message
78 */
79void reportError(const char* errorMsg);
80
Sampa Misra032bd502019-03-06 05:03:22 -060081/** @brief Convert any Decimal number to BCD
82 *
83 * @tparam[in] decimal - Decimal number
84 * @return Corresponding BCD number
85 */
86template <typename T>
87T decimalToBcd(T decimal)
88{
89 T bcd = 0;
90 T rem = 0;
91 auto cnt = 0;
92
93 while (decimal)
94 {
95 rem = decimal % 10;
96 bcd = bcd + (rem << cnt);
97 decimal = decimal / 10;
98 cnt += 4;
99 }
100
101 return bcd;
102}
103
Sampa Misraa2fa0702019-05-31 01:28:55 -0500104constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
105
106/**
107 * @class DBusHandler
108 *
109 * Wrapper class to handle the D-Bus calls
110 *
111 * This class contains the APIs to handle the D-Bus calls
112 * to cater the request from pldm requester.
113 * A class is created to mock the apis in the test cases
114 */
115class DBusHandler
116{
117 public:
118 /** @brief API to set a D-Bus property
119 *
120 * @param[in] objPath - Object path for the D-Bus object
121 * @param[in] dbusProp - The D-Bus property
122 * @param[in] dbusInterface - The D-Bus interface
123 * @param[in] value - The value to be set
124 * failure
125 */
126 template <typename T>
127 void setDbusProperty(const char* objPath, const char* dbusProp,
128 const char* dbusInterface,
129 const std::variant<T>& value) const
130 {
131 auto bus = sdbusplus::bus::new_default();
132 auto service = getService(bus, objPath, dbusInterface);
133 auto method = bus.new_method_call(service.c_str(), objPath,
134 dbusProperties, "Set");
135 method.append(dbusInterface, dbusProp, value);
136 bus.call_noreply(method);
137 }
John Wang92b3c972019-10-17 11:06:41 +0800138
139 template <typename Variant>
140 auto getDbusPropertyVariant(const char* objPath, const char* dbusProp,
141 const char* dbusInterface)
142 {
John Wang92b3c972019-10-17 11:06:41 +0800143 Variant value;
144 auto bus = sdbusplus::bus::new_default();
145 auto service = getService(bus, objPath, dbusInterface);
146 auto method = bus.new_method_call(service.c_str(), objPath,
147 dbusProperties, "Get");
148 method.append(dbusInterface, dbusProp);
149 try
150 {
151 auto reply = bus.call(method);
152 reply.read(value);
153 }
154 catch (const sdbusplus::exception::SdBusError& e)
155 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600156 std::cerr << "dbus call exception, OBJPATH=" << objPath
157 << " INTERFACE=" << dbusInterface
158 << " PROPERTY=" << dbusProp << " EXCEPTION=" << e.what()
159 << "\n";
John Wang92b3c972019-10-17 11:06:41 +0800160 }
161 return value;
162 }
163
164 template <typename Property>
165 auto getDbusProperty(const char* objPath, const char* dbusProp,
166 const char* dbusInterface)
167 {
168 auto VariantValue = getDbusPropertyVariant<std::variant<Property>>(
169 objPath, dbusProp, dbusInterface);
170 return std::get<Property>(VariantValue);
171 }
Sampa Misraa2fa0702019-05-31 01:28:55 -0500172};
173
Sampa Misra032bd502019-03-06 05:03:22 -0600174} // namespace responder
175} // namespace pldm