blob: b1fd8b663914ad047e357090154b4207f69cabce [file] [log] [blame]
George Liuf3b75142021-06-10 11:22:50 +08001#include "utils.hpp"
2
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +05303#include <phosphor-logging/elog-errors.hpp>
Gunnar Mills94df8c92018-09-14 14:50:03 -05004#include <sdbusplus/bus.hpp>
5#include <string>
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +05306#include <xyz/openbmc_project/Common/error.hpp>
7namespace open_power
8{
9namespace occ
10{
George Liuf3b75142021-06-10 11:22:50 +080011namespace utils
12{
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053013// For throwing exceptions
14using namespace phosphor::logging;
Gunnar Mills94df8c92018-09-14 14:50:03 -050015using InternalFailure =
16 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053017
George Liuf3b75142021-06-10 11:22:50 +080018const std::string getService(const std::string& path,
19 const std::string& interface)
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053020{
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053021
George Liuf3b75142021-06-10 11:22:50 +080022 using InterfaceList = std::vector<std::string>;
23 std::map<std::string, std::vector<std::string>> mapperResponse;
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053024
George Liuf3b75142021-06-10 11:22:50 +080025 auto& bus = getBus();
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053026
George Liuf3b75142021-06-10 11:22:50 +080027 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
28 MAPPER_IFACE, "GetObject");
29 mapper.append(path, InterfaceList({interface}));
30
31 auto mapperResponseMsg = bus.call(mapper);
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053032 if (mapperResponseMsg.is_method_error())
33 {
34 log<level::ERR>("ERROR in getting service",
Gunnar Mills94df8c92018-09-14 14:50:03 -050035 entry("PATH=%s", path.c_str()),
George Liuf3b75142021-06-10 11:22:50 +080036 entry("INTERFACE=%s", interface.c_str()));
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053037
38 elog<InternalFailure>();
39 }
40
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053041 mapperResponseMsg.read(mapperResponse);
George Liuf3b75142021-06-10 11:22:50 +080042 if (mapperResponse.empty())
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053043 {
44 log<level::ERR>("ERROR reading mapper response",
Gunnar Mills94df8c92018-09-14 14:50:03 -050045 entry("PATH=%s", path.c_str()),
George Liuf3b75142021-06-10 11:22:50 +080046 entry("INTERFACE=%s", interface.c_str()));
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053047
48 elog<InternalFailure>();
49 }
George Liuf3b75142021-06-10 11:22:50 +080050
51 // the value here will be the service name
52 return mapperResponse.cbegin()->first;
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053053}
54
George Liuf3b75142021-06-10 11:22:50 +080055const PropertyValue getProperty(const std::string& objectPath,
56 const std::string& interface,
57 const std::string& propertyName)
58{
59 PropertyValue value{};
60
61 auto& bus = getBus();
62 auto service = getService(objectPath, interface);
63 if (service.empty())
64 {
65 return value;
66 }
67
68 auto method = bus.new_method_call(service.c_str(), objectPath.c_str(),
69 DBUS_PROPERTY_IFACE, "Get");
70 method.append(interface, propertyName);
71
72 auto reply = bus.call(method);
73 reply.read(value);
74
75 return value;
76}
77
George Liu13901592021-06-03 14:13:21 +080078std::optional<LABELVALUE> checkLabelValue(const std::string& value)
79{
80 // The ID 0xD0000002 is only 4 bytes long, but when converted to a string it
81 // is 8 characters long
82 // eg: Dimm2, the lable file is `D0000002` so value
83 // length = 2 byte(type) + 2 byte(reserve) + 4 byte(instace ID)
84 size_t valueLen = value.length();
85 size_t typeLen = 2;
86 size_t reserveLen = 2;
87 size_t instanceIDLen = 4;
88 if (valueLen != typeLen + reserveLen + instanceIDLen)
89 {
90 return std::nullopt;
91 }
92
93 size_t offset = 0;
94 std::string type = value.substr(offset, typeLen);
95 offset += typeLen;
96 std::string reserve = value.substr(offset, reserveLen);
97 offset += reserveLen;
98
99 if ("00" != reserve)
100 {
101 return std::nullopt;
102 }
103
104 const char* start = value.data() + offset;
105 uint16_t instanceID = static_cast<uint16_t>(std::strtol(start, NULL, 16));
106
107 LABELVALUE labelValue{type, instanceID};
108
109 return std::make_optional(std::move(labelValue));
110}
111
George Liuf3b75142021-06-10 11:22:50 +0800112} // namespace utils
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530113} // namespace occ
114} // namespace open_power