1 #include "guid.hpp"
2 
3 #include <iostream>
4 #include <sstream>
5 #include <string>
6 
7 #include <host-ipmid/ipmid-api.h>
8 #include <mapper.h>
9 
10 namespace command
11 {
12 
13 std::array<uint8_t, BMC_GUID_LEN> getSystemGUID()
14 {
15     // Canned System GUID for QEMU where the Chassis DBUS object is not
16     // populated
17     std::array<uint8_t, BMC_GUID_LEN> guid = { 0x01, 0x02, 0x03, 0x04,
18                                                0x05, 0x06, 0x07, 0x08,
19                                                0x09, 0x0A, 0x0B, 0x0C,
20                                                0x0D, 0x0E, 0x0F, 0x10
21                                              };
22 
23     constexpr auto objname = "/org/openbmc/control/chassis0";
24     constexpr auto interface = "org.freedesktop.DBus.Properties";
25     constexpr auto chassisIntf = "org.openbmc.control.Chassis";
26 
27     sd_bus_message* reply = nullptr;
28     sd_bus_error error = SD_BUS_ERROR_NULL;
29     sd_bus* bus = ipmid_get_sd_bus_connection();
30     int rc = 0;
31     char* uuid = nullptr;
32     char* busname = nullptr;
33 
34     do
35     {
36         rc = mapper_get_service(bus, objname, &busname);
37         if (rc < 0)
38         {
39             std::cerr << "Failed to get " << objname << " bus name: "
40                       << strerror(-rc) << "\n";
41             break;
42         }
43 
44         rc = sd_bus_call_method(bus, busname, objname, interface, "Get", &error,
45                                 &reply, "ss", chassisIntf, "uuid");
46         if (rc < 0)
47         {
48             std::cerr << "Failed to call Get Method:" << strerror(-rc) << "\n";
49             break;
50         }
51 
52         rc = sd_bus_message_read(reply, "v", "s", &uuid);
53         if (rc < 0 || uuid == NULL)
54         {
55             std::cerr << "Failed to get a response:" << strerror(-rc) << "\n";
56             break;
57         }
58 
59         std::string readUUID(uuid);
60         auto len = readUUID.length();
61 
62         for (size_t iter = 0, inc = 0;
63              iter < len && inc < BMC_GUID_LEN; iter += 2, inc++)
64         {
65             uint8_t hexVal = std::strtoul(readUUID.substr(iter, 2).c_str(),
66                                           NULL, 16);
67             guid[inc] = hexVal;
68         }
69     }
70     while (0);
71 
72     sd_bus_error_free(&error);
73     reply = sd_bus_message_unref(reply);
74     free(busname);
75 
76     return guid;
77 }
78 
79 } // namespace command
80