blob: 5e92f4a5ee65adb8c2d81e2c3c151f9d952146f7 [file] [log] [blame]
Lei YU5e0dcb32019-08-02 18:04:34 +08001#include "config.h"
2
3#include "utils.hpp"
4
Lei YUad90ad52019-08-06 11:19:28 +08005#include <openssl/sha.h>
6
Lei YU5e0dcb32019-08-02 18:04:34 +08007#include <fstream>
Lei YUf77189f2019-08-07 14:26:30 +08008#include <phosphor-logging/log.hpp>
9
10using namespace phosphor::logging;
Lei YU5e0dcb32019-08-02 18:04:34 +080011
12namespace utils
13{
14
15namespace // anonymous
16{
17constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
18constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
19constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
20} // namespace
21
Lei YUf77189f2019-08-07 14:26:30 +080022const UtilsInterface& getUtils()
23{
24 static Utils utils;
25 return utils;
26}
27
28std::vector<std::string>
29 Utils::getPSUInventoryPath(sdbusplus::bus::bus& bus) const
Lei YU5e0dcb32019-08-02 18:04:34 +080030{
31 std::vector<std::string> paths;
32 auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
33 MAPPER_INTERFACE, "GetSubTreePaths");
34 method.append(PSU_INVENTORY_PATH_BASE);
35 method.append(0); // Depth 0 to search all
36 method.append(std::vector<std::string>({PSU_INVENTORY_IFACE}));
37 auto reply = bus.call(method);
38
39 reply.read(paths);
40 return paths;
41}
42
Lei YUf77189f2019-08-07 14:26:30 +080043std::string Utils::getService(sdbusplus::bus::bus& bus, const char* path,
44 const char* interface) const
Lei YUad90ad52019-08-06 11:19:28 +080045{
46 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
47 MAPPER_INTERFACE, "GetObject");
48
49 mapper.append(path, std::vector<std::string>({interface}));
50 try
51 {
52 auto mapperResponseMsg = bus.call(mapper);
53
54 std::vector<std::pair<std::string, std::vector<std::string>>>
55 mapperResponse;
56 mapperResponseMsg.read(mapperResponse);
57 if (mapperResponse.empty())
58 {
59 log<level::ERR>("Error reading mapper response");
60 throw std::runtime_error("Error reading mapper response");
61 }
62 if (mapperResponse.size() < 1)
63 {
64 return "";
65 }
66 return mapperResponse[0].first;
67 }
68 catch (const sdbusplus::exception::SdBusError& ex)
69 {
70 log<level::ERR>("Mapper call failed", entry("METHOD=%d", "GetObject"),
71 entry("PATH=%s", path),
72 entry("INTERFACE=%s", interface));
73 throw std::runtime_error("Mapper call failed");
74 }
75}
76
Lei YUf77189f2019-08-07 14:26:30 +080077std::string Utils::getVersionId(const std::string& version) const
Lei YUad90ad52019-08-06 11:19:28 +080078{
79 if (version.empty())
80 {
81 log<level::ERR>("Error version is empty");
82 return {};
83 }
84
85 unsigned char digest[SHA512_DIGEST_LENGTH];
86 SHA512_CTX ctx;
87 SHA512_Init(&ctx);
88 SHA512_Update(&ctx, version.c_str(), strlen(version.c_str()));
89 SHA512_Final(digest, &ctx);
90 char mdString[SHA512_DIGEST_LENGTH * 2 + 1];
91 for (int i = 0; i < SHA512_DIGEST_LENGTH; i++)
92 {
93 snprintf(&mdString[i * 2], 3, "%02x", (unsigned int)digest[i]);
94 }
95
96 // Only need 8 hex digits.
97 std::string hexId = std::string(mdString);
98 return (hexId.substr(0, 8));
99}
100
Lei YUf77189f2019-08-07 14:26:30 +0800101any Utils::getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
102 const char* path, const char* interface,
103 const char* propertyName) const
104{
105 auto method = bus.new_method_call(service, path,
106 "org.freedesktop.DBus.Properties", "Get");
107 method.append(interface, propertyName);
108 try
109 {
110 PropertyType value{};
111 auto reply = bus.call(method);
112 reply.read(value);
113 return any(value);
114 }
115 catch (const sdbusplus::exception::SdBusError& ex)
116 {
117 log<level::ERR>("GetProperty call failed", entry("PATH=%s", path),
118 entry("INTERFACE=%s", interface),
119 entry("PROPERTY=%s", propertyName));
120 throw std::runtime_error("GetProperty call failed");
121 }
122}
123
Lei YU5e0dcb32019-08-02 18:04:34 +0800124} // namespace utils