blob: 98e8d2123f86ecdb0184ff74b1ecee95f78cdf6c [file] [log] [blame]
George Liu83409572019-12-24 18:42:54 +08001#include "utils.hpp"
2
3#include <array>
4#include <ctime>
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05005#include <fstream>
George Liu83409572019-12-24 18:42:54 +08006#include <iostream>
7#include <map>
George Liu83409572019-12-24 18:42:54 +08008#include <stdexcept>
9#include <string>
10#include <vector>
11#include <xyz/openbmc_project/Common/error.hpp>
12
13namespace pldm
14{
15namespace utils
16{
17
18constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper";
19constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper";
20constexpr auto mapperInterface = "xyz.openbmc_project.ObjectMapper";
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050021constexpr auto eidPath = "/usr/share/pldm/host_eid";
22
23uint8_t readHostEID()
24{
25 uint8_t eid{};
26 std::ifstream eidFile{eidPath};
27 if (!eidFile.good())
28 {
29 std::cerr << "Could not open host EID file"
30 << "\n";
31 }
32 else
33 {
34 std::string eidStr;
35 eidFile >> eidStr;
36 if (!eidStr.empty())
37 {
38 eid = atoi(eidStr.c_str());
39 }
40 else
41 {
42 std::cerr << "Host EID file was empty"
43 << "\n";
44 }
45 }
46
47 return eid;
48}
George Liu83409572019-12-24 18:42:54 +080049
50uint8_t getNumPadBytes(uint32_t data)
51{
52 uint8_t pad;
53 pad = ((data % 4) ? (4 - data % 4) : 0);
54 return pad;
55} // end getNumPadBytes
56
57bool uintToDate(uint64_t data, uint16_t* year, uint8_t* month, uint8_t* day,
58 uint8_t* hour, uint8_t* min, uint8_t* sec)
59{
60 constexpr uint64_t max_data = 29991231115959;
61 constexpr uint64_t min_data = 19700101000000;
62 if (data < min_data || data > max_data)
63 {
64 return false;
65 }
66
67 *year = data / 10000000000;
68 data = data % 10000000000;
69 *month = data / 100000000;
70 data = data % 100000000;
71 *day = data / 1000000;
72 data = data % 1000000;
73 *hour = data / 10000;
74 data = data % 10000;
75 *min = data / 100;
76 *sec = data % 100;
77
78 return true;
79}
80
George Liuba4c1fb2020-02-05 14:13:30 +080081std::optional<std::vector<set_effecter_state_field>>
82 parseEffecterData(const std::vector<uint8_t>& effecterData,
83 uint8_t effecterCount)
George Liu83409572019-12-24 18:42:54 +080084{
George Liuba4c1fb2020-02-05 14:13:30 +080085 std::vector<set_effecter_state_field> stateField;
86
87 if (effecterData.size() != effecterCount * 2)
George Liu83409572019-12-24 18:42:54 +080088 {
George Liuba4c1fb2020-02-05 14:13:30 +080089 return std::nullopt;
George Liu83409572019-12-24 18:42:54 +080090 }
91
George Liuba4c1fb2020-02-05 14:13:30 +080092 for (uint8_t i = 0; i < effecterCount; ++i)
George Liu83409572019-12-24 18:42:54 +080093 {
George Liuba4c1fb2020-02-05 14:13:30 +080094 uint8_t set_request = effecterData[i * 2] == PLDM_REQUEST_SET
95 ? PLDM_REQUEST_SET
96 : PLDM_NO_CHANGE;
97 set_effecter_state_field filed{set_request, effecterData[i * 2 + 1]};
98 stateField.emplace_back(std::move(filed));
George Liu83409572019-12-24 18:42:54 +080099 }
100
George Liuba4c1fb2020-02-05 14:13:30 +0800101 return std::make_optional(std::move(stateField));
George Liu83409572019-12-24 18:42:54 +0800102}
103
George Liu0e02c322020-01-01 09:41:51 +0800104std::string DBusHandler::getService(const char* path,
105 const char* interface) const
George Liu83409572019-12-24 18:42:54 +0800106{
107 using DbusInterfaceList = std::vector<std::string>;
108 std::map<std::string, std::vector<std::string>> mapperResponse;
George Liu0e02c322020-01-01 09:41:51 +0800109 auto& bus = DBusHandler::getBus();
George Liu83409572019-12-24 18:42:54 +0800110
George Liu0e02c322020-01-01 09:41:51 +0800111 auto mapper = bus.new_method_call(mapperBusName, mapperPath,
112 mapperInterface, "GetObject");
113 mapper.append(path, DbusInterfaceList({interface}));
George Liu83409572019-12-24 18:42:54 +0800114
George Liu0e02c322020-01-01 09:41:51 +0800115 auto mapperResponseMsg = bus.call(mapper);
116 mapperResponseMsg.read(mapperResponse);
George Liu83409572019-12-24 18:42:54 +0800117 return mapperResponse.begin()->first;
118}
119
120void reportError(const char* errorMsg)
121{
122 static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
123 static constexpr auto logInterface = "xyz.openbmc_project.Logging.Create";
124
George Liu0e02c322020-01-01 09:41:51 +0800125 auto& bus = pldm::utils::DBusHandler::getBus();
George Liu83409572019-12-24 18:42:54 +0800126
127 try
128 {
George Liu0e02c322020-01-01 09:41:51 +0800129 auto service = DBusHandler().getService(logObjPath, logInterface);
George Liu83409572019-12-24 18:42:54 +0800130 using namespace sdbusplus::xyz::openbmc_project::Logging::server;
131 auto severity =
132 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
133 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
134 Error);
135 auto method = bus.new_method_call(service.c_str(), logObjPath,
136 logInterface, "Create");
137 std::map<std::string, std::string> addlData{};
138 method.append(errorMsg, severity, addlData);
139 bus.call_noreply(method);
140 }
141 catch (const std::exception& e)
142 {
143 std::cerr << "failed to make a d-bus call to create error log, ERROR="
144 << e.what() << "\n";
145 }
146}
147
George Liu1e44c732020-02-28 20:20:06 +0800148void DBusHandler::setDbusProperty(const DBusMapping& dBusMap,
149 const PropertyValue& value) const
150{
151 auto setDbusValue = [&dBusMap, this](const auto& variant) {
152 auto& bus = getBus();
153 auto service =
154 getService(dBusMap.objectPath.c_str(), dBusMap.interface.c_str());
155 auto method = bus.new_method_call(
156 service.c_str(), dBusMap.objectPath.c_str(), dbusProperties, "Set");
157 method.append(dBusMap.interface.c_str(), dBusMap.propertyName.c_str(),
158 variant);
159 bus.call_noreply(method);
160 };
161
162 if (dBusMap.propertyType == "uint8_t")
163 {
164 std::variant<uint8_t> v = std::get<uint8_t>(value);
165 setDbusValue(v);
166 }
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600167 else if (dBusMap.propertyType == "bool")
168 {
169 std::variant<bool> v = std::get<bool>(value);
170 setDbusValue(v);
171 }
George Liu1e44c732020-02-28 20:20:06 +0800172 else if (dBusMap.propertyType == "int16_t")
173 {
174 std::variant<int16_t> v = std::get<int16_t>(value);
175 setDbusValue(v);
176 }
177 else if (dBusMap.propertyType == "uint16_t")
178 {
179 std::variant<uint16_t> v = std::get<uint16_t>(value);
180 setDbusValue(v);
181 }
182 else if (dBusMap.propertyType == "int32_t")
183 {
184 std::variant<int32_t> v = std::get<int32_t>(value);
185 setDbusValue(v);
186 }
187 else if (dBusMap.propertyType == "uint32_t")
188 {
189 std::variant<uint32_t> v = std::get<uint32_t>(value);
190 setDbusValue(v);
191 }
192 else if (dBusMap.propertyType == "int64_t")
193 {
194 std::variant<int64_t> v = std::get<int64_t>(value);
195 setDbusValue(v);
196 }
197 else if (dBusMap.propertyType == "uint64_t")
198 {
199 std::variant<uint64_t> v = std::get<uint64_t>(value);
200 setDbusValue(v);
201 }
202 else if (dBusMap.propertyType == "double")
203 {
204 std::variant<double> v = std::get<double>(value);
205 setDbusValue(v);
206 }
207 else if (dBusMap.propertyType == "string")
208 {
209 std::variant<std::string> v = std::get<std::string>(value);
210 setDbusValue(v);
211 }
212 else
213 {
214 throw std::invalid_argument("UnSpported Dbus Type");
215 }
216}
217
John Wang9e242422020-03-05 08:37:50 +0800218PropertyValue DBusHandler::getDbusPropertyVariant(
219 const char* objPath, const char* dbusProp, const char* dbusInterface) const
220{
221 auto& bus = DBusHandler::getBus();
222 auto service = getService(objPath, dbusInterface);
223 auto method =
224 bus.new_method_call(service.c_str(), objPath, dbusProperties, "Get");
225 method.append(dbusInterface, dbusProp);
226 PropertyValue value{};
227 auto reply = bus.call(method);
228 reply.read(value);
229 return value;
230}
231
George Liu83409572019-12-24 18:42:54 +0800232} // namespace utils
233} // namespace pldm