blob: 4fdece869a21b785948e9f03dd33555563247673 [file] [log] [blame]
Tom Josephf8da32a2016-12-06 16:56:04 +05301#include "guid.hpp"
2
William A. Kennington III4f09eae2019-02-12 17:10:35 -08003#include <ipmid/api.h>
Vernon Mauery9e801a22018-10-12 13:20:49 -07004#include <mapper.h>
5
Xie Ning94b0d132023-01-13 16:53:56 +08006#include <ipmid/utils.hpp>
7#include <phosphor-logging/elog-errors.hpp>
George Liu7b7f25f2022-07-04 17:07:32 +08008#include <phosphor-logging/lg2.hpp>
Xie Ning94b0d132023-01-13 16:53:56 +08009#include <xyz/openbmc_project/Common/error.hpp>
George Liubc8958f2022-07-04 09:29:49 +080010
Tom Josephf8da32a2016-12-06 16:56:04 +053011#include <sstream>
12#include <string>
13
Vernon Maueryfc37e592018-12-19 14:55:15 -080014using namespace phosphor::logging;
Xie Ning94b0d132023-01-13 16:53:56 +080015using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Vernon Maueryfc37e592018-12-19 14:55:15 -080016
Vernon Mauery36e3c532023-07-31 19:28:18 -070017static std::optional<command::Guid> guid;
Tom Joseph83029cb2017-09-01 16:37:31 +053018
Tom Josephf8da32a2016-12-06 16:56:04 +053019namespace command
20{
21
Tom Joseph83029cb2017-09-01 16:37:31 +053022std::unique_ptr<sdbusplus::bus::match_t> matchPtr(nullptr);
23
Xie Ning94b0d132023-01-13 16:53:56 +080024static constexpr auto propInterface = "xyz.openbmc_project.Common.UUID";
25static constexpr auto uuidProperty = "UUID";
Vernon Mauery36e3c532023-07-31 19:28:18 -070026static constexpr auto subtreePath = "/xyz/openbmc_project/inventory";
Xie Ning94b0d132023-01-13 16:53:56 +080027
28static void rfcToGuid(std::string rfc4122, Guid& uuid)
29{
30 using Argument = xyz::openbmc_project::Common::InvalidArgument;
31 // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
32 // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte
33 // order
34 // Ex: 0x2332fc2c40e66298e511f2782395a361
35 constexpr size_t uuidHexLength = (2 * BMC_GUID_LEN);
36 constexpr size_t uuidRfc4122Length = (uuidHexLength + 4);
37
38 if (rfc4122.size() == uuidRfc4122Length)
39 {
40 rfc4122.erase(std::remove(rfc4122.begin(), rfc4122.end(), '-'),
41 rfc4122.end());
42 }
43 if (rfc4122.size() != uuidHexLength)
44 {
45 elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
46 Argument::ARGUMENT_VALUE(rfc4122.c_str()));
47 }
48 for (size_t ind = 0; ind < uuidHexLength; ind += 2)
49 {
50 long b;
51 try
52 {
53 b = std::stoul(rfc4122.substr(ind, 2), nullptr, 16);
54 }
55 catch (const std::exception& e)
56 {
57 elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
58 Argument::ARGUMENT_VALUE(rfc4122.c_str()));
59 }
60
61 uuid[BMC_GUID_LEN - (ind / 2) - 1] = static_cast<uint8_t>(b);
62 }
63 return;
64}
Tom Joseph83029cb2017-09-01 16:37:31 +053065
Vernon Mauery36e3c532023-07-31 19:28:18 -070066// Canned System GUID for when the Chassis DBUS object is not populated
67static constexpr Guid fakeGuid = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
68 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
69 0x0D, 0x0E, 0x0F, 0x10};
70const Guid& getSystemGUID()
Tom Josephf8da32a2016-12-06 16:56:04 +053071{
Vernon Mauery36e3c532023-07-31 19:28:18 -070072 if (guid.has_value())
73 {
74 return guid.value();
75 }
Tom Josephf8da32a2016-12-06 16:56:04 +053076
Xie Ning94b0d132023-01-13 16:53:56 +080077 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Tom Josephf8da32a2016-12-06 16:56:04 +053078
Xie Ning94b0d132023-01-13 16:53:56 +080079 ipmi::Value propValue;
80 try
Tom Josephf8da32a2016-12-06 16:56:04 +053081 {
Vernon Mauery36e3c532023-07-31 19:28:18 -070082 const auto& [objPath, service] = ipmi::getDbusObject(bus, propInterface,
83 subtreePath);
Xie Ning94b0d132023-01-13 16:53:56 +080084 // Read UUID property value from bmcObject
85 // UUID is in RFC4122 format Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
Vernon Mauery36e3c532023-07-31 19:28:18 -070086 propValue = ipmi::getDbusProperty(bus, service, objPath, propInterface,
Xie Ning94b0d132023-01-13 16:53:56 +080087 uuidProperty);
88 }
89 catch (const sdbusplus::exception_t& e)
90 {
91 lg2::error("Failed in reading BMC UUID property: {ERROR}", "ERROR", e);
Vernon Mauery36e3c532023-07-31 19:28:18 -070092 return fakeGuid;
Xie Ning94b0d132023-01-13 16:53:56 +080093 }
Tom Josephf8da32a2016-12-06 16:56:04 +053094
Xie Ning94b0d132023-01-13 16:53:56 +080095 std::string rfc4122Uuid = std::get<std::string>(propValue);
96 try
97 {
98 // convert to IPMI format
Vernon Mauery36e3c532023-07-31 19:28:18 -070099 Guid tmpGuid{};
100 rfcToGuid(rfc4122Uuid, tmpGuid);
101 guid = tmpGuid;
Xie Ning94b0d132023-01-13 16:53:56 +0800102 }
103 catch (const InvalidArgument& e)
104 {
105 lg2::error("Failed in parsing BMC UUID property: {VALUE}", "VALUE",
106 rfc4122Uuid.c_str());
Vernon Mauery36e3c532023-07-31 19:28:18 -0700107 return fakeGuid;
Xie Ning94b0d132023-01-13 16:53:56 +0800108 }
Vernon Mauery36e3c532023-07-31 19:28:18 -0700109 return guid.value();
Tom Josephf8da32a2016-12-06 16:56:04 +0530110}
111
Tom Joseph83029cb2017-09-01 16:37:31 +0530112void registerGUIDChangeCallback()
113{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700114 if (matchPtr == nullptr)
Tom Joseph83029cb2017-09-01 16:37:31 +0530115 {
116 using namespace sdbusplus::bus::match::rules;
Patrick Williams0a590622022-07-22 19:26:53 -0500117 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Tom Joseph83029cb2017-09-01 16:37:31 +0530118
Vernon Mauery36e3c532023-07-31 19:28:18 -0700119 try
120 {
121 matchPtr = std::make_unique<sdbusplus::bus::match_t>(
122 bus, propertiesChangedNamespace(subtreePath, propInterface),
123 [](sdbusplus::message_t& m) {
124 try
125 {
126 std::string iface{};
127 std::map<std::string, ipmi::Value> pdict{};
128 m.read(iface, pdict);
129 if (iface != propInterface)
130 {
131 return;
132 }
133 auto guidStr = std::get<std::string>(pdict.at("UUID"));
134 Guid tmpGuid{};
135 rfcToGuid(guidStr, tmpGuid);
136 guid = tmpGuid;
137 }
138 catch (const std::exception& e)
139 {
140 // signal contained invalid guid; ignore it
141 lg2::error(
142 "Failed to parse propertiesChanged signal: {ERROR}",
143 "ERROR", e);
144 }
145 });
146 }
147 catch (const std::exception& e)
148 {
149 lg2::error("Failed to create dbus match: {ERROR}", "ERROR", e);
150 }
Tom Joseph83029cb2017-09-01 16:37:31 +0530151 }
152}
153
Tom Josephf8da32a2016-12-06 16:56:04 +0530154} // namespace command