blob: 944f34ff346263a6abd98e9fa28ffc10c424c532 [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
Tom Joseph83029cb2017-09-01 16:37:31 +053017namespace cache
18{
19
20command::Guid guid;
Xie Ning94b0d132023-01-13 16:53:56 +080021std::string guidObjService = "";
22std::string guidObjPath = "";
Tom Joseph83029cb2017-09-01 16:37:31 +053023
24} // namespace cache
25
Tom Josephf8da32a2016-12-06 16:56:04 +053026namespace command
27{
28
Tom Joseph83029cb2017-09-01 16:37:31 +053029std::unique_ptr<sdbusplus::bus::match_t> matchPtr(nullptr);
30
Xie Ning94b0d132023-01-13 16:53:56 +080031static constexpr auto propInterface = "xyz.openbmc_project.Common.UUID";
32static constexpr auto uuidProperty = "UUID";
33static constexpr auto subtreePath = "/xyz/openbmc_project/inventory/";
34
35void getUIDObjectInfo()
36{
37 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
38 ipmi::DbusObjectInfo bmcObject;
39 try
40 {
41 // Get the Inventory object implementing BMC interface
42 bmcObject = ipmi::getDbusObject(bus, propInterface, subtreePath);
43 }
44 catch (const sdbusplus::exception_t& e)
45 {
46 lg2::error("Failed in reading BMC UUID property: {ERROR}", "ERROR", e);
47 return;
48 }
49
50 cache::guidObjService = bmcObject.second;
51 cache::guidObjPath = bmcObject.first;
52 return;
53}
54
55static void rfcToGuid(std::string rfc4122, Guid& uuid)
56{
57 using Argument = xyz::openbmc_project::Common::InvalidArgument;
58 // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
59 // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte
60 // order
61 // Ex: 0x2332fc2c40e66298e511f2782395a361
62 constexpr size_t uuidHexLength = (2 * BMC_GUID_LEN);
63 constexpr size_t uuidRfc4122Length = (uuidHexLength + 4);
64
65 if (rfc4122.size() == uuidRfc4122Length)
66 {
67 rfc4122.erase(std::remove(rfc4122.begin(), rfc4122.end(), '-'),
68 rfc4122.end());
69 }
70 if (rfc4122.size() != uuidHexLength)
71 {
72 elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
73 Argument::ARGUMENT_VALUE(rfc4122.c_str()));
74 }
75 for (size_t ind = 0; ind < uuidHexLength; ind += 2)
76 {
77 long b;
78 try
79 {
80 b = std::stoul(rfc4122.substr(ind, 2), nullptr, 16);
81 }
82 catch (const std::exception& e)
83 {
84 elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
85 Argument::ARGUMENT_VALUE(rfc4122.c_str()));
86 }
87
88 uuid[BMC_GUID_LEN - (ind / 2) - 1] = static_cast<uint8_t>(b);
89 }
90 return;
91}
Tom Joseph83029cb2017-09-01 16:37:31 +053092
93Guid getSystemGUID()
Tom Josephf8da32a2016-12-06 16:56:04 +053094{
95 // Canned System GUID for QEMU where the Chassis DBUS object is not
96 // populated
Vernon Mauery9e801a22018-10-12 13:20:49 -070097 Guid guid = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
98 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};
Tom Josephf8da32a2016-12-06 16:56:04 +053099
Xie Ning94b0d132023-01-13 16:53:56 +0800100 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Tom Josephf8da32a2016-12-06 16:56:04 +0530101
Xie Ning94b0d132023-01-13 16:53:56 +0800102 ipmi::Value propValue;
103 try
Tom Josephf8da32a2016-12-06 16:56:04 +0530104 {
Xie Ning94b0d132023-01-13 16:53:56 +0800105 // Read UUID property value from bmcObject
106 // UUID is in RFC4122 format Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
107 propValue = ipmi::getDbusProperty(bus, cache::guidObjService,
108 cache::guidObjPath, propInterface,
109 uuidProperty);
110 }
111 catch (const sdbusplus::exception_t& e)
112 {
113 lg2::error("Failed in reading BMC UUID property: {ERROR}", "ERROR", e);
114 return guid;
115 }
Tom Josephf8da32a2016-12-06 16:56:04 +0530116
Xie Ning94b0d132023-01-13 16:53:56 +0800117 std::string rfc4122Uuid = std::get<std::string>(propValue);
118 try
119 {
120 // convert to IPMI format
121 rfcToGuid(rfc4122Uuid, guid);
122 }
123 catch (const InvalidArgument& e)
124 {
125 lg2::error("Failed in parsing BMC UUID property: {VALUE}", "VALUE",
126 rfc4122Uuid.c_str());
127 return guid;
128 }
Tom Josephf8da32a2016-12-06 16:56:04 +0530129
130 return guid;
131}
132
Tom Joseph83029cb2017-09-01 16:37:31 +0530133void registerGUIDChangeCallback()
134{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700135 if (matchPtr == nullptr)
Tom Joseph83029cb2017-09-01 16:37:31 +0530136 {
137 using namespace sdbusplus::bus::match::rules;
Patrick Williams0a590622022-07-22 19:26:53 -0500138 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Tom Joseph83029cb2017-09-01 16:37:31 +0530139
140 matchPtr = std::make_unique<sdbusplus::bus::match_t>(
Xie Ning94b0d132023-01-13 16:53:56 +0800141 bus, propertiesChanged(cache::guidObjPath, propInterface),
Patrick Williams0a590622022-07-22 19:26:53 -0500142 [](sdbusplus::message_t&) { cache::guid = getSystemGUID(); });
Tom Joseph83029cb2017-09-01 16:37:31 +0530143 }
144}
145
Tom Josephf8da32a2016-12-06 16:56:04 +0530146} // namespace command