blob: 20d2b061fd5ecd88cd10dfc545df940e402aadc3 [file] [log] [blame]
George Liu83409572019-12-24 18:42:54 +08001#include "utils.hpp"
2
3#include <array>
4#include <ctime>
5#include <iostream>
6#include <map>
George Liu83409572019-12-24 18:42:54 +08007#include <stdexcept>
8#include <string>
9#include <vector>
10#include <xyz/openbmc_project/Common/error.hpp>
11
12namespace pldm
13{
14namespace utils
15{
16
17constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper";
18constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper";
19constexpr auto mapperInterface = "xyz.openbmc_project.ObjectMapper";
20
21uint8_t getNumPadBytes(uint32_t data)
22{
23 uint8_t pad;
24 pad = ((data % 4) ? (4 - data % 4) : 0);
25 return pad;
26} // end getNumPadBytes
27
28bool uintToDate(uint64_t data, uint16_t* year, uint8_t* month, uint8_t* day,
29 uint8_t* hour, uint8_t* min, uint8_t* sec)
30{
31 constexpr uint64_t max_data = 29991231115959;
32 constexpr uint64_t min_data = 19700101000000;
33 if (data < min_data || data > max_data)
34 {
35 return false;
36 }
37
38 *year = data / 10000000000;
39 data = data % 10000000000;
40 *month = data / 100000000;
41 data = data % 100000000;
42 *day = data / 1000000;
43 data = data % 1000000;
44 *hour = data / 10000;
45 data = data % 10000;
46 *min = data / 100;
47 *sec = data % 100;
48
49 return true;
50}
51
George Liuba4c1fb2020-02-05 14:13:30 +080052std::optional<std::vector<set_effecter_state_field>>
53 parseEffecterData(const std::vector<uint8_t>& effecterData,
54 uint8_t effecterCount)
George Liu83409572019-12-24 18:42:54 +080055{
George Liuba4c1fb2020-02-05 14:13:30 +080056 std::vector<set_effecter_state_field> stateField;
57
58 if (effecterData.size() != effecterCount * 2)
George Liu83409572019-12-24 18:42:54 +080059 {
George Liuba4c1fb2020-02-05 14:13:30 +080060 return std::nullopt;
George Liu83409572019-12-24 18:42:54 +080061 }
62
George Liuba4c1fb2020-02-05 14:13:30 +080063 for (uint8_t i = 0; i < effecterCount; ++i)
George Liu83409572019-12-24 18:42:54 +080064 {
George Liuba4c1fb2020-02-05 14:13:30 +080065 uint8_t set_request = effecterData[i * 2] == PLDM_REQUEST_SET
66 ? PLDM_REQUEST_SET
67 : PLDM_NO_CHANGE;
68 set_effecter_state_field filed{set_request, effecterData[i * 2 + 1]};
69 stateField.emplace_back(std::move(filed));
George Liu83409572019-12-24 18:42:54 +080070 }
71
George Liuba4c1fb2020-02-05 14:13:30 +080072 return std::make_optional(std::move(stateField));
George Liu83409572019-12-24 18:42:54 +080073}
74
George Liu0e02c322020-01-01 09:41:51 +080075std::string DBusHandler::getService(const char* path,
76 const char* interface) const
George Liu83409572019-12-24 18:42:54 +080077{
78 using DbusInterfaceList = std::vector<std::string>;
79 std::map<std::string, std::vector<std::string>> mapperResponse;
George Liu0e02c322020-01-01 09:41:51 +080080 auto& bus = DBusHandler::getBus();
George Liu83409572019-12-24 18:42:54 +080081
George Liu0e02c322020-01-01 09:41:51 +080082 auto mapper = bus.new_method_call(mapperBusName, mapperPath,
83 mapperInterface, "GetObject");
84 mapper.append(path, DbusInterfaceList({interface}));
George Liu83409572019-12-24 18:42:54 +080085
George Liu0e02c322020-01-01 09:41:51 +080086 auto mapperResponseMsg = bus.call(mapper);
87 mapperResponseMsg.read(mapperResponse);
George Liu83409572019-12-24 18:42:54 +080088 return mapperResponse.begin()->first;
89}
90
91void reportError(const char* errorMsg)
92{
93 static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
94 static constexpr auto logInterface = "xyz.openbmc_project.Logging.Create";
95
George Liu0e02c322020-01-01 09:41:51 +080096 auto& bus = pldm::utils::DBusHandler::getBus();
George Liu83409572019-12-24 18:42:54 +080097
98 try
99 {
George Liu0e02c322020-01-01 09:41:51 +0800100 auto service = DBusHandler().getService(logObjPath, logInterface);
George Liu83409572019-12-24 18:42:54 +0800101 using namespace sdbusplus::xyz::openbmc_project::Logging::server;
102 auto severity =
103 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
104 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
105 Error);
106 auto method = bus.new_method_call(service.c_str(), logObjPath,
107 logInterface, "Create");
108 std::map<std::string, std::string> addlData{};
109 method.append(errorMsg, severity, addlData);
110 bus.call_noreply(method);
111 }
112 catch (const std::exception& e)
113 {
114 std::cerr << "failed to make a d-bus call to create error log, ERROR="
115 << e.what() << "\n";
116 }
117}
118
George Liu1e44c732020-02-28 20:20:06 +0800119void DBusHandler::setDbusProperty(const DBusMapping& dBusMap,
120 const PropertyValue& value) const
121{
122 auto setDbusValue = [&dBusMap, this](const auto& variant) {
123 auto& bus = getBus();
124 auto service =
125 getService(dBusMap.objectPath.c_str(), dBusMap.interface.c_str());
126 auto method = bus.new_method_call(
127 service.c_str(), dBusMap.objectPath.c_str(), dbusProperties, "Set");
128 method.append(dBusMap.interface.c_str(), dBusMap.propertyName.c_str(),
129 variant);
130 bus.call_noreply(method);
131 };
132
133 if (dBusMap.propertyType == "uint8_t")
134 {
135 std::variant<uint8_t> v = std::get<uint8_t>(value);
136 setDbusValue(v);
137 }
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600138 else if (dBusMap.propertyType == "bool")
139 {
140 std::variant<bool> v = std::get<bool>(value);
141 setDbusValue(v);
142 }
George Liu1e44c732020-02-28 20:20:06 +0800143 else if (dBusMap.propertyType == "int16_t")
144 {
145 std::variant<int16_t> v = std::get<int16_t>(value);
146 setDbusValue(v);
147 }
148 else if (dBusMap.propertyType == "uint16_t")
149 {
150 std::variant<uint16_t> v = std::get<uint16_t>(value);
151 setDbusValue(v);
152 }
153 else if (dBusMap.propertyType == "int32_t")
154 {
155 std::variant<int32_t> v = std::get<int32_t>(value);
156 setDbusValue(v);
157 }
158 else if (dBusMap.propertyType == "uint32_t")
159 {
160 std::variant<uint32_t> v = std::get<uint32_t>(value);
161 setDbusValue(v);
162 }
163 else if (dBusMap.propertyType == "int64_t")
164 {
165 std::variant<int64_t> v = std::get<int64_t>(value);
166 setDbusValue(v);
167 }
168 else if (dBusMap.propertyType == "uint64_t")
169 {
170 std::variant<uint64_t> v = std::get<uint64_t>(value);
171 setDbusValue(v);
172 }
173 else if (dBusMap.propertyType == "double")
174 {
175 std::variant<double> v = std::get<double>(value);
176 setDbusValue(v);
177 }
178 else if (dBusMap.propertyType == "string")
179 {
180 std::variant<std::string> v = std::get<std::string>(value);
181 setDbusValue(v);
182 }
183 else
184 {
185 throw std::invalid_argument("UnSpported Dbus Type");
186 }
187}
188
John Wang9e242422020-03-05 08:37:50 +0800189PropertyValue DBusHandler::getDbusPropertyVariant(
190 const char* objPath, const char* dbusProp, const char* dbusInterface) const
191{
192 auto& bus = DBusHandler::getBus();
193 auto service = getService(objPath, dbusInterface);
194 auto method =
195 bus.new_method_call(service.c_str(), objPath, dbusProperties, "Get");
196 method.append(dbusInterface, dbusProp);
197 PropertyValue value{};
198 auto reply = bus.call(method);
199 reply.read(value);
200 return value;
201}
202
George Liu83409572019-12-24 18:42:54 +0800203} // namespace utils
204} // namespace pldm