xref: /openbmc/phosphor-net-ipmid/command/guid.cpp (revision fc37e59e2f85e585ee830e801b5b26a2c859c86b)
1f8da32adSTom Joseph #include "guid.hpp"
2f8da32adSTom Joseph 
39e801a2bSVernon Mauery #include <host-ipmid/ipmid-api.h>
49e801a2bSVernon Mauery #include <mapper.h>
59e801a2bSVernon Mauery 
6*fc37e59eSVernon Mauery #include <phosphor-logging/log.hpp>
7f8da32adSTom Joseph #include <sstream>
8f8da32adSTom Joseph #include <string>
9f8da32adSTom Joseph 
10*fc37e59eSVernon Mauery using namespace phosphor::logging;
11*fc37e59eSVernon Mauery 
1283029cb8STom Joseph namespace cache
1383029cb8STom Joseph {
1483029cb8STom Joseph 
1583029cb8STom Joseph command::Guid guid;
1683029cb8STom Joseph 
1783029cb8STom Joseph } // namespace cache
1883029cb8STom Joseph 
19f8da32adSTom Joseph namespace command
20f8da32adSTom Joseph {
21f8da32adSTom Joseph 
2283029cb8STom Joseph std::unique_ptr<sdbusplus::bus::match_t> matchPtr(nullptr);
2383029cb8STom Joseph 
2483029cb8STom Joseph static constexpr auto guidObjPath = "/org/openbmc/control/chassis0";
2583029cb8STom Joseph static constexpr auto propInterface = "org.freedesktop.DBus.Properties";
2683029cb8STom Joseph 
2783029cb8STom Joseph Guid getSystemGUID()
28f8da32adSTom Joseph {
29f8da32adSTom Joseph     // Canned System GUID for QEMU where the Chassis DBUS object is not
30f8da32adSTom Joseph     // populated
3183029cb8STom Joseph     Guid guid = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
3283029cb8STom Joseph                  0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};
33f8da32adSTom Joseph 
34f8da32adSTom Joseph     constexpr auto chassisIntf = "org.openbmc.control.Chassis";
35f8da32adSTom Joseph 
36f8da32adSTom Joseph     sd_bus_message* reply = nullptr;
37f8da32adSTom Joseph     sd_bus_error error = SD_BUS_ERROR_NULL;
38f8da32adSTom Joseph     sd_bus* bus = ipmid_get_sd_bus_connection();
39f8da32adSTom Joseph     char* uuid = nullptr;
40f8da32adSTom Joseph     char* busname = nullptr;
41f8da32adSTom Joseph 
42f8da32adSTom Joseph     do
43f8da32adSTom Joseph     {
44a65e30dfSPatrick Venture         int rc = mapper_get_service(bus, guidObjPath, &busname);
45f8da32adSTom Joseph         if (rc < 0)
46f8da32adSTom Joseph         {
47*fc37e59eSVernon Mauery             log<level::ERR>("Failed to get bus name",
48*fc37e59eSVernon Mauery                             entry("PATH=%s", guidObjPath),
49*fc37e59eSVernon Mauery                             entry("ERROR=%s", strerror(-rc)));
50f8da32adSTom Joseph             break;
51f8da32adSTom Joseph         }
52f8da32adSTom Joseph 
5383029cb8STom Joseph         rc = sd_bus_call_method(bus, busname, guidObjPath, propInterface, "Get",
5483029cb8STom Joseph                                 &error, &reply, "ss", chassisIntf, "uuid");
55f8da32adSTom Joseph         if (rc < 0)
56f8da32adSTom Joseph         {
57*fc37e59eSVernon Mauery             log<level::ERR>("Failed to call Get Method",
58*fc37e59eSVernon Mauery                             entry("ERROR=%s", strerror(-rc)));
59f8da32adSTom Joseph             break;
60f8da32adSTom Joseph         }
61f8da32adSTom Joseph 
62f8da32adSTom Joseph         rc = sd_bus_message_read(reply, "v", "s", &uuid);
63f8da32adSTom Joseph         if (rc < 0 || uuid == NULL)
64f8da32adSTom Joseph         {
65*fc37e59eSVernon Mauery             log<level::ERR>("Failed to get a response",
66*fc37e59eSVernon Mauery                             entry("ERROR=%s", strerror(-rc)));
67f8da32adSTom Joseph             break;
68f8da32adSTom Joseph         }
69f8da32adSTom Joseph 
70f8da32adSTom Joseph         std::string readUUID(uuid);
71f8da32adSTom Joseph         auto len = readUUID.length();
72f8da32adSTom Joseph 
739e801a2bSVernon Mauery         for (size_t iter = 0, inc = 0; iter < len && inc < BMC_GUID_LEN;
749e801a2bSVernon Mauery              iter += 2, inc++)
75f8da32adSTom Joseph         {
769e801a2bSVernon Mauery             uint8_t hexVal =
779e801a2bSVernon Mauery                 std::strtoul(readUUID.substr(iter, 2).c_str(), NULL, 16);
78f8da32adSTom Joseph             guid[inc] = hexVal;
79f8da32adSTom Joseph         }
809e801a2bSVernon Mauery     } while (0);
81f8da32adSTom Joseph 
82f8da32adSTom Joseph     sd_bus_error_free(&error);
83f8da32adSTom Joseph     reply = sd_bus_message_unref(reply);
84f8da32adSTom Joseph     free(busname);
85f8da32adSTom Joseph 
86f8da32adSTom Joseph     return guid;
87f8da32adSTom Joseph }
88f8da32adSTom Joseph 
8983029cb8STom Joseph void registerGUIDChangeCallback()
9083029cb8STom Joseph {
9183029cb8STom Joseph     if (matchPtr == nullptr)
9283029cb8STom Joseph     {
9383029cb8STom Joseph         using namespace sdbusplus::bus::match::rules;
9483029cb8STom Joseph         sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
9583029cb8STom Joseph 
9683029cb8STom Joseph         matchPtr = std::make_unique<sdbusplus::bus::match_t>(
9783029cb8STom Joseph             bus,
989e801a2bSVernon Mauery             path_namespace(guidObjPath) + type::signal() +
999e801a2bSVernon Mauery                 member("PropertiesChanged") + interface(propInterface),
1009e801a2bSVernon Mauery             [](sdbusplus::message::message&) {
1019e801a2bSVernon Mauery                 cache::guid = getSystemGUID();
1029e801a2bSVernon Mauery             });
10383029cb8STom Joseph     }
10483029cb8STom Joseph }
10583029cb8STom Joseph 
106f8da32adSTom Joseph } // namespace command
107