xref: /openbmc/phosphor-net-ipmid/command/guid.cpp (revision 83029cb8ede836420e3c4d13e20968b661b6a2e4)
1f8da32adSTom Joseph #include "guid.hpp"
2f8da32adSTom Joseph 
3f8da32adSTom Joseph #include <iostream>
4f8da32adSTom Joseph #include <sstream>
5f8da32adSTom Joseph #include <string>
6f8da32adSTom Joseph 
7f8da32adSTom Joseph #include <host-ipmid/ipmid-api.h>
8f8da32adSTom Joseph #include <mapper.h>
9f8da32adSTom Joseph 
10*83029cb8STom Joseph namespace cache
11*83029cb8STom Joseph {
12*83029cb8STom Joseph 
13*83029cb8STom Joseph command::Guid guid;
14*83029cb8STom Joseph 
15*83029cb8STom Joseph } // namespace cache
16*83029cb8STom Joseph 
17f8da32adSTom Joseph namespace command
18f8da32adSTom Joseph {
19f8da32adSTom Joseph 
20*83029cb8STom Joseph std::unique_ptr<sdbusplus::bus::match_t> matchPtr(nullptr);
21*83029cb8STom Joseph 
22*83029cb8STom Joseph static constexpr auto guidObjPath = "/org/openbmc/control/chassis0";
23*83029cb8STom Joseph static constexpr auto propInterface = "org.freedesktop.DBus.Properties";
24*83029cb8STom Joseph 
25*83029cb8STom Joseph Guid getSystemGUID()
26f8da32adSTom Joseph {
27f8da32adSTom Joseph     // Canned System GUID for QEMU where the Chassis DBUS object is not
28f8da32adSTom Joseph     // populated
29*83029cb8STom Joseph     Guid guid = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
30*83029cb8STom Joseph                   0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };
31f8da32adSTom Joseph 
32f8da32adSTom Joseph     constexpr auto chassisIntf = "org.openbmc.control.Chassis";
33f8da32adSTom Joseph 
34f8da32adSTom Joseph     sd_bus_message* reply = nullptr;
35f8da32adSTom Joseph     sd_bus_error error = SD_BUS_ERROR_NULL;
36f8da32adSTom Joseph     sd_bus* bus = ipmid_get_sd_bus_connection();
37f8da32adSTom Joseph     int rc = 0;
38f8da32adSTom Joseph     char* uuid = nullptr;
39f8da32adSTom Joseph     char* busname = nullptr;
40f8da32adSTom Joseph 
41f8da32adSTom Joseph     do
42f8da32adSTom Joseph     {
43*83029cb8STom Joseph         rc = mapper_get_service(bus, guidObjPath, &busname);
44f8da32adSTom Joseph         if (rc < 0)
45f8da32adSTom Joseph         {
46*83029cb8STom Joseph             std::cerr << "Failed to get " << guidObjPath << " bus name: "
47f8da32adSTom Joseph                       << strerror(-rc) << "\n";
48f8da32adSTom Joseph             break;
49f8da32adSTom Joseph         }
50f8da32adSTom Joseph 
51*83029cb8STom Joseph         rc = sd_bus_call_method(bus, busname, guidObjPath, propInterface, "Get",
52*83029cb8STom Joseph                                 &error, &reply, "ss", chassisIntf, "uuid");
53f8da32adSTom Joseph         if (rc < 0)
54f8da32adSTom Joseph         {
55f8da32adSTom Joseph             std::cerr << "Failed to call Get Method:" << strerror(-rc) << "\n";
56f8da32adSTom Joseph             break;
57f8da32adSTom Joseph         }
58f8da32adSTom Joseph 
59f8da32adSTom Joseph         rc = sd_bus_message_read(reply, "v", "s", &uuid);
60f8da32adSTom Joseph         if (rc < 0 || uuid == NULL)
61f8da32adSTom Joseph         {
62f8da32adSTom Joseph             std::cerr << "Failed to get a response:" << strerror(-rc) << "\n";
63f8da32adSTom Joseph             break;
64f8da32adSTom Joseph         }
65f8da32adSTom Joseph 
66f8da32adSTom Joseph         std::string readUUID(uuid);
67f8da32adSTom Joseph         auto len = readUUID.length();
68f8da32adSTom Joseph 
69f8da32adSTom Joseph         for (size_t iter = 0, inc = 0;
70f8da32adSTom Joseph              iter < len && inc < BMC_GUID_LEN; iter += 2, inc++)
71f8da32adSTom Joseph         {
72f8da32adSTom Joseph             uint8_t hexVal = std::strtoul(readUUID.substr(iter, 2).c_str(),
73f8da32adSTom Joseph                                           NULL, 16);
74f8da32adSTom Joseph             guid[inc] = hexVal;
75f8da32adSTom Joseph         }
76f8da32adSTom Joseph     }
77f8da32adSTom Joseph     while (0);
78f8da32adSTom Joseph 
79f8da32adSTom Joseph     sd_bus_error_free(&error);
80f8da32adSTom Joseph     reply = sd_bus_message_unref(reply);
81f8da32adSTom Joseph     free(busname);
82f8da32adSTom Joseph 
83f8da32adSTom Joseph     return guid;
84f8da32adSTom Joseph }
85f8da32adSTom Joseph 
86*83029cb8STom Joseph void registerGUIDChangeCallback()
87*83029cb8STom Joseph {
88*83029cb8STom Joseph     if(matchPtr == nullptr)
89*83029cb8STom Joseph     {
90*83029cb8STom Joseph         using namespace sdbusplus::bus::match::rules;
91*83029cb8STom Joseph         sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
92*83029cb8STom Joseph 
93*83029cb8STom Joseph         matchPtr = std::make_unique<sdbusplus::bus::match_t>(
94*83029cb8STom Joseph             bus,
95*83029cb8STom Joseph             path_namespace(guidObjPath) +
96*83029cb8STom Joseph             type::signal() +
97*83029cb8STom Joseph             member("PropertiesChanged") +
98*83029cb8STom Joseph             interface(propInterface),
99*83029cb8STom Joseph             [](sdbusplus::message::message&){cache::guid = getSystemGUID();});
100*83029cb8STom Joseph     }
101*83029cb8STom Joseph }
102*83029cb8STom Joseph 
103f8da32adSTom Joseph } // namespace command
104